gpt4 book ai didi

rust - 为什么添加第二个 impl 会阻止对参数的 deref 强制?

转载 作者:行者123 更新时间:2023-12-03 11:23:20 25 4
gpt4 key购买 nike

我在尝试将 impl Add<char> for String 添加到标准库时遇到了这个问题。但是我们可以轻松复制它,无需运算符(operator)恶作剧。我们从这个开始:

trait MyAdd<Rhs> {
fn add(self, rhs: Rhs) -> Self;
}

impl MyAdd<&str> for String {
fn add(mut self, rhs: &str) -> Self {
self.push_str(rhs);
self
}
}

足够简单。有了这个,下面的代码编译:

let a = String::from("a");
let b = String::from("b");
MyAdd::add(a, &b);

请注意,在这种情况下,第二个参数表达式 ( &b) 的类型为 &String。然后它被 deref 强制转换为 &str 并且函数调用起作用。

但是,让我们尝试添加以下实现:

impl MyAdd<char> for String {
fn add(mut self, rhs: char) -> Self {
self.push(rhs);
self
}
}

( Everything on Playground )

现在上面的 MyAdd::add(a, &b) 表达式导致以下错误:

error[E0277]: the trait bound `std::string::String: MyAdd<&std::string::String>` is not satisfied
--> src/main.rs:24:5
|
2 | fn add(self, rhs: Rhs) -> Self;
| ------------------------------- required by `MyAdd::add`
...
24 | MyAdd::add(a, &b);
| ^^^^^^^^^^ the trait `MyAdd<&std::string::String>` is not implemented for `std::string::String`
|
= help: the following implementations were found:
<std::string::String as MyAdd<&str>>
<std::string::String as MyAdd<char>>

为什么会这样? 对我来说,似乎只有在只有一个候选函数时才会进行解引用强制。但这对我来说似乎是错误的。为什么会有这样的规则?我尝试查看规范,但我没有发现任何关于参数 deref 强制的内容。

最佳答案

正如您自己解释的那样,编译器会处理只有一个有效 impl 的情况。特别地,并且可以使用它来驱动类型推断:

Here is a comment which states that if only one impl is found the compiler "eagerly confirms" it, which allows deref coercions (among other things) to happen. That does not happen for multiple impl candidates.



第二部分是 deref 强制只会发生在预期类型已知的站点,它不会凭推测发生。见 coercion sites在引用。 impl选择和类型推断必须首先明确地找到 MyAdd::add(&str)预计会尝试将参数强制转换为 &str .

如果在这种情况下需要解决方法,请使用类似 &*b 的表达式。或 &b[..]b.as_str()对于第二个论点。

关于rust - 为什么添加第二个 impl 会阻止对参数的 deref 强制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58889717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com