Rust方法调用的行为在The Rust Reference中进行了描述.它声明"在查找方法调用时,为了调用方法,接收方可能会自动取消引用或borrow ."这一行为将在本章更详细地解释.
在本例中,您可以看到into_char
移动Suit
,而to_char
borrow Suit
.
-
into_char
,则它由一个值和一个引用调用,并且该引用自动取消引用. -
to_char
,则它也被值和引用调用,并且该值被自动borrow .
对于值和引用Suit
都实现了From
.因此,当被值调用时,调用Into<Suit>::into()
,并且当被引用调用时,调用Into<&Suit>::into()
.
However, shouldn't I only need to implement one of these traits? When I comment out either implementation the Rust compiler does not compile...个
这个过程似乎是这样的.首先生成一个"候选接收器类型"列表.这是通过"反复取消引用",最后"在最后try 一个巨大的胁迫"来实现的.此外,"对于每个候选人T,将&;T和&;mut T添加到紧接在T之后的列表中."然后,对于这些"候选接收器类型"中的每一个,寻找"直接在T上实现的方法"和"由T实现的可见特征提供的方法".
假设只为char
实现了From<Suit>
.那么应该对char
执行Into<Suit>
.
-
当调用
let c: char = value.into();
时,"候选接收器类型"应至少包含Suit
、&Suit
和&mut Suit
.然后,很容易为列表中的第一项解析Into<T>::into()
.因此,Into<Suit>::into()
被称为. -
但是,当调用
let f: char = reference.into();
时,"候选接收器类型"也应该至少包含&Suit
、&&Suit
、&mut &Suit
、*&Suit = Suit
、&Suit
(再次)和&mut Suit
.则Into<T>::into()
找不到&Suit
、&&Suit
和&mut &Suit
的实现,但随后找到*&Suit = Suit
的实现.因此,Into<Suit>::into()
被称为Into<Suit>::into()
.
Is my logic correct? Why doesn't this work if I comment-out one of the 100 implementations?
#[derive(Clone, Copy)]
pub enum Suit {
Club,
Diamond,
Heart,
Spade,
}
pub use Suit::*;
impl Suit {
#[inline(never)]
pub fn into_char(self) -> char {
match self {
Club => 'C',
Diamond => 'D',
Heart => 'H',
Spade => 'S',
}
}
#[inline(never)]
pub fn to_char(&self) -> char {
match self {
Club => 'C',
Diamond => 'D',
Heart => 'H',
Spade => 'S',
}
}
}
impl std::convert::From<Suit> for char {
fn from(suit: Suit) -> Self {
suit.into_char()
}
}
impl std::convert::From<&Suit> for char {
fn from(suit: &Suit) -> Self {
suit.to_char()
}
}
fn main() {
let value = Club;
let reference = &value;
let a: char = value.into_char();
let b: char = value.to_char();
let c: char = value.into();
println!("{}, {}, {}", a, b, c);
let d: char = reference.into_char();
let e: char = reference.to_char();
let f: char = reference.into();
println!("{}, {}, {}", d, e, f);
}
编辑:正如下面讨论的,我创建了better reproduction%的问题,这确实有助于缩小导致这种行为的原因.