Rust中结构体与Trait多次impl后方法调用不符如何解决?
Rust中同名方法调用优先级问题排查与解决
原始代码
mod m { pub trait Foo { fn xyzzy(&self) { println!("foo!"); } } pub trait Bar { fn xyzzy(&self) { println!("bar!"); } } pub trait Quux: Foo+Bar { fn xyzzy(&self) { println!("quux!"); } } pub struct X; impl X { pub fn xyzzy(&self) { println!("XXXXX self!"); } } impl Foo for X {} impl Bar for X {} impl Quux for X {} } use m::X; fn main() { let x = X; x.xyzzy(); { use m::Foo; x.xyzzy(); // 预期输出 "foo!" } { use m::Quux; x.xyzzy(); // 预期输出 "quux!" } }
问题现象
- 预期输出:
XXXXX self! foo! quux!
- 实际输出:
XXXXX self! XXXXX self! XXXXX self!
问题原因
Rust的方法解析规则中,结构体自身定义的关联方法优先级远高于trait中的默认方法。即使通过use导入了对应的trait,编译器在解析方法调用时,会优先匹配结构体自身的同名方法,不会去考虑trait中的实现。
解决方案
要调用trait中的方法,必须使用完全限定语法明确指定要调用的trait方法,不能依赖use导入来隐式切换。修改后的代码如下:
mod m { pub trait Foo { fn xyzzy(&self) { println!("foo!"); } } pub trait Bar { fn xyzzy(&self) { println!("bar!"); } } pub trait Quux: Foo+Bar { fn xyzzy(&self) { println!("quux!"); } } pub struct X; impl X { pub fn xyzzy(&self) { println!("XXXXX self!"); } } impl Foo for X {} impl Bar for X {} impl Quux for X {} } use m::{X, Foo, Quux}; fn main() { let x = X; // 调用结构体自身的方法 x.xyzzy(); // 调用Foo trait的方法 Foo::xyzzy(&x); // 调用Quux trait的方法 Quux::xyzzy(&x); }
代码说明
- 使用
TraitName::method_name(&instance)的语法,可以强制编译器调用指定trait中的方法,绕过结构体自身的方法优先级 - 也可以使用更明确的
<Type as Trait>::method_name(&instance)写法,比如<X as Foo>::xyzzy(&x),效果完全一致
运行修改后的代码,输出将符合预期:
XXXXX self! foo! quux!
内容的提问来源于stack exchange,提问作者James Yang
相关产品推荐
相关产品推荐

