为何Rust中调用self的方法不会触发无限递归?
为什么这段Rust代码不会触发无限递归?
你可能会疑惑,在为Foo实现FFF trait的is_empty方法中调用self.is_empty(),为什么没有触发无限递归,反而调用了Foo自身定义的is_empty方法?
原代码
struct Foo{} impl Foo{ pub fn is_empty(&self) -> Option<bool>{ Some(true) } } trait FFF { fn is_empty(&self) -> Option<bool>; } impl FFF for Foo { fn is_empty(&self) -> Option<bool>{ println!("calling FFF"); self.is_empty() } } fn pr<F:FFF>(a:F){ println!("{:?}", a.is_empty()); } fn main() { pr(Foo{}); }
运行输出
calling FFF Some(true)
原因解析
这是Rust方法调用的优先级规则导致的:当类型自身和它实现的trait拥有同名方法时,直接通过self.方法名()调用时,编译器会优先选择类型自身定义的关联方法,而不是trait中的方法。
如果想要触发无限递归(也就是调用trait的is_empty方法),你需要显式指定调用路径,明确告诉编译器要调用trait的方法,示例如下:
impl FFF for Foo { fn is_empty(&self) -> Option<bool>{ println!("calling FFF"); // 明确调用FFF trait的is_empty方法,会触发无限递归 FFF::is_empty(self) // 或者用<Self as FFF>::is_empty(self),效果一致 } }
修改后运行这段代码,程序会不断打印calling FFF,直到栈溢出,也就是你原本预期的无限递归行为。
内容的提问来源于stack exchange,提问作者Guy Korland
相关产品推荐
相关产品推荐

