Rust中如何区分trait实现与struct实现的同名函数调用?
如何区分结构体直接实现与Trait实现的同名方法
我写了一段Rust代码,给两个结构体分别直接实现了get_field_helper_function方法,同时也为这两个结构体实现了包含同名方法的DTODynamic trait。目前遇到的情况:
- 调用
get_field_helper_function时,会优先执行结构体的直接实现,而非trait的实现 - 若移除结构体的直接实现,才会调用trait的实现
但当两者同时存在时,我不知道该怎么分别调用这两个不同的实现,看起来trait实现的优先级更低。
示例代码
struct FirstType { field_1: String } impl FirstType { pub fn get_field_helper_function(&self) -> String { println!("FirstType::get_field_helper_function()"); self.field_1.clone() } } struct SecondType { field_2: String } impl SecondType { pub fn get_field_helper_function(&self) -> String { println!("SecondType::get_field_helper_function()"); self.field_2.clone() } } trait DTODynamic { fn get_field(&self) -> String; fn get_field_helper_function(&self) -> String; } fn from_str(struct_name: &str) -> Option<Box<dyn DTODynamic>> { match struct_name { "FirstType" => { let first = FirstType { field_1: String::from("first") }; return Some(Box::new(first)); } "SecondType" => { let second = SecondType { field_2: String::from("second") }; return Some(Box::new(second)); } _ => { return None; } } } impl DTODynamic for FirstType { fn get_field(&self) -> String { println!("DTODynamic::FirstType::get_field()"); self.get_field_helper_function() } fn get_field_helper_function(&self) -> String { println!("DTODynamic::FirstType::get_field_helper_function()"); self.field_1.clone() } } impl DTODynamic for SecondType { fn get_field(&self) -> String { println!("DTODynamic::SecondType::get_field()"); self.get_field_helper_function() } fn get_field_helper_function(&self) -> String { println!("DTODynamic::SecondType::get_field_helper_function()"); self.field_2.clone() } } fn main() { println!("constructing dynamic objects from function return value"); let dynamic_thing = from_str("FirstType").expect("value was None"); println!("dynamic_thing.get_field()={}", dynamic_thing.get_field()); }
代码输出(两种情况)
结构体直接实现存在时的输出
constructing dynamic objects from function return value DTODynamic::FirstType::get_field() FirstType::get_field_helper_function() dynamic_thing.get_field()=first
移除FirstType::get_field_helper_function后的输出
constructing dynamic objects from function return value DTODynamic::FirstType::get_field() DTODynamic::FirstType::get_field_helper_function() dynamic_thing.get_field()=first
解决方案:显式指定调用目标
在Rust中,当结构体的直接方法和其实现的trait方法同名时,直接调用self.get_field_helper_function()会优先匹配结构体自身的方法。如果想调用trait中的实现,需要通过显式限定trait名称来调用:
1. 在trait实现中调用trait版本的方法
如果想在DTODynamic的get_field方法里强制调用trait版本的get_field_helper_function,修改代码如下:
impl DTODynamic for FirstType { fn get_field(&self) -> String { println!("DTODynamic::FirstType::get_field()"); // 显式指定调用DTODynamic trait中的方法 DTODynamic::get_field_helper_function(self) } // ... 其他实现 }
2. 针对结构体实例分别调用不同版本
如果你持有FirstType的具体实例,想要分别调用两种实现:
fn main() { let first = FirstType { field_1: "test".into() }; // 调用结构体自身的方法 first.get_field_helper_function(); // 调用DTODynamic trait中的方法 DTODynamic::get_field_helper_function(&first); }
3. 动态分发场景的注意事项
当你持有Box<dyn DTODynamic>这类动态对象时,方法调用默认走trait的动态分发,但如果结构体自身有同名方法,在trait的实现中直接调用self.xxx()仍会优先匹配结构体自身的方法——这正是你示例中出现的情况,此时必须用显式限定trait的方式来调用trait版本的方法。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

