【问题标题】:How can I avoid consuming a value passed to an `impl Trait` parameter?如何避免使用传递给“impl Trait”参数的值?
【发布时间】:2023-01-09 06:59:21
【问题描述】:

在将值传递给以 impl Trait 作为参数的函数后,如何继续使用值的所有权?我已经尝试过将参数作为参考传递并且没有 & 但它们都不起作用。

trait Noise{
    fn make_noise(&self);
    fn call_by_name(&self);
}

struct Person {
    name: String,
}

impl Noise for Person{
    fn make_noise(&self){
        println!("Hello");
    }

    fn call_by_name(&self) {
        println!("Hey, {:?}, how are you doing?", self.name)
    }
}

fn talk(noisy: impl Noise){
    noisy.make_noise();
}

fn main() {
    let john_person= Person{name:String::from("John")};
    talk(john_person); 
    john_person.call_by_name(); // ERROR WHEN CALLING THE FUNCTION.
}

【问题讨论】:

    标签: rust borrow-checker trait-objects


    【解决方案1】:

    您应该使 fn talk 通过引用而不是通过值获取特征对象:

    trait Noise {
        fn make_noise(&self);
        fn call_by_name(&self);
    }
    
    struct Person {
        name: String,
    }
    
    impl Noise for Person {
        fn make_noise(&self) {
            println!("Hello");
        }
    
        fn call_by_name(&self) {
            println!("Hey, {:?}, how are you doing?", self.name)
        }
    }
    
    fn talk(noisy: &impl Noise) {  // <- used &impl Noise
        noisy.make_noise();
    }
    
    fn main() {
        let john_person = Person {
            name: String::from("John"),
        };
        talk(&john_person);           // call by reference, not move
        john_person.call_by_name();
    }
    

    否则,john_person 将移至函数talk。这意味着您无法再访问它。

    如果通过引用传递它,它将被借用直到函数结束。

    【讨论】:

    • 答案很好,但有一点措辞问题。在 Rust 中,一切都按值传递,即使你传递的是引用。因此,与其说“通过引用传递”(这意味着其他含义),不如说“传递引用”。
    • @jthulhu 我不明白为什么我们需要将所有内容归类为按值传递。当然,如果您要传递引用,那么您就是在复制引用,我能想到的每种语言都是这种情况。但这并不能使一切都按值传递,因为它是一个概念性的东西,可以帮助您理解和区分复制整个结构与复制结构的地址。我知道有些人称 Java 总是按值传递,原因类似,但 IMO 没有多大意义,也没有真正帮助。
    猜你喜欢
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多