如何在 Rust 中通过 Trait function impl 和 struct impl 消除函数调用之间的歧义?

问题描述 投票:0回答:1

下面的示例代码演示了两个结构体以及“本机?”的特征的实现。直接为两个结构体使用相同名称的函数 impl 。 (希望这是有道理的。)

如果还不清楚:

  • 有一个特征定义了一个名为
    get_field_helper_function
  • 的函数
  • 这个特质对于两个
    impl
    s
    来说是
    struct
  • 相同的函数名称用作相同两个结构的
    impl
    块的一部分

我想知道的是如何消除这两个函数调用之间的歧义。

下面示例代码的输出包含在代码本身下方。

这说明:

  • 函数
    get_field_helper_function
    是从 struct impl 调用的,而不是从 Trait impl
  • 如果我删除此函数,则会调用特征 impl

但是如果这两个函数都存在,我不知道如何消除它们之间的歧义。似乎特征实现的优先级低于直接实现。


示例代码

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 traits
1个回答
0
投票

这两个函数调用可以使用完全限定语法以通常的方式消除歧义,但解决方案的关键是,由于在这个特定实例中函数采用

&self
参数,因此必须修改函数调用的形式因为通常的形式

self.get_field_helper_function()

不起作用。相反,必须将

self
作为第一个参数显式传递。

以下为示例:

impl DTODynamic for FirstType {
    
    fn get_field(&self) -> String {
        println!("DTODynamic::FirstType::get_field()");
        DTODynamic::get_field_helper_function(self)
    }
    
    fn get_field_helper_function(&self) -> String {
        println!("DTODynamic::FirstType::get_field_helper_function()");
        //self.field_1.clone()
        self.get_field_helper_function()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.