在阅读了method-call expressions、dereference operator、method lookup和auto-dereferencing之后,我认为我对这门学科有了相当好的理解;但后来我遇到了一种情况,在这种情况下,我预期会发生自动解引用,而事实上它并没有发生.
下面是一个例子.
#[derive(Clone, Copy, Debug)]
struct Foo();
impl Into<&'static str> for Foo {
fn into(self) -> &'static str {
"<Foo as Into>::into"
}
}
fn vec_into<F: Copy + Into<T>, T>(slice: &[F]) -> Vec<T> {
slice.iter().map(|x| (*x).into()).collect()
}
fn main() {
let array = [Foo(), Foo(), Foo()];
let vec = vec_into::<_, &'static str>(&array);
println!("{:?}", vec);
}
上面的代码可以工作,但我认为不需要函数vec_into
中的显式解引用(*x).into()
.我的推理是,既然x: &Foo
,那么x.into()
会试图找到接受类型&Foo
、&&Foo
、&mut &Foo
、Foo
、&Foo
、&mut Foo
的方法.
这是因为存在解引用&Foo
的链→ 我们在这条链上分别插入&mut U
和Foo
.
我的直觉得到了以下事实的证实:下面的代码也可以工作,没有任何明确的取消引用.
#[derive(Clone, Copy, Debug)]
struct Foo();
trait MyInto<T> {
fn my_into(self) -> T;
}
impl MyInto<&'static str> for Foo {
fn my_into(self) -> &'static str {
"<Foo as MyInto>::my_into"
}
}
fn vec_my_into<F: Copy + MyInto<T>, T>(slice: &[F]) -> Vec<T> {
slice.iter().map(|x| x.my_into()).collect()
}
fn main() {
let array = [Foo(), Foo(), Foo()];
let my_vec = vec_my_into(&array);
println!("{:?}", my_vec);
}
这里,x: &Foo
被隐式地解引用以调用方法<Foo as MyInto<&'static str>>::my_into
.
A smaller example
鉴于上述Foo
和MyInto
的定义
let result: &str = (&Foo()).my_into()
有效,但是
let result: &str = (&Foo()).into()
未能编译,但出现错误
error[E0277]: the trait bound `&str: std::convert::From<&Foo>` is not satisfied
--> src/bin/into.rs:34:33
|
34 | let result: &str = (&Foo()).into();
| ^^^^ the trait `std::convert::From<&Foo>` is not implemented for `&str`
|
= note: required because of the requirements on the impl of `std::convert::Into<&str>` for `&Foo`