【发布时间】:2021-02-07 13:32:09
【问题描述】:
我有一个具有某种关联类型的特征,它的一些函数将该类型的引用作为输入:
trait Trait {
type Value;
fn do_something(&self, value: &Self::Value);
}
在一个实现此特征的结构中,Value 是一个元组,因为我需要将多个值传递给do_something:
struct Struct {}
impl Trait for Struct {
type Value = (i64, String);
fn do_something(&self, (a, b): &(i64, String)) {
println!("{} {}", a, b);
}
}
但是,当我在实践中使用Struct 时,我碰壁了。要么我这样做:
fn main() {
let a = 10;
let b = "foo".to_owned();
let s = Struct {};
s.do_something(&(a, b)); // This works...
println!("{}", b); // ...but the borrow checker complains here
}
但是我失去了元组中任何非Copy 类型的所有权。或者,我可以这样做:
fn main() {
let a = 10;
let b = "foo".to_owned();
let s = Struct {};
let t = (a, b);
s.do_something(&t);
let (a, b) = t;
println!("{}", b);
}
可行,但语法非常繁重。
有没有人知道如何以更简洁的方式完成我想要的事情?我试图让Struct::Value 的类型为(&i64, &String),但是借用检查器抱怨这些引用需要一个生命周期,如果可能的话我想避免这种情况。
我尝试的另一种选择是使用类型参数(即Trait<Value>)而不是关联类型。在这种情况下,我可以让Struct 实现Trait<(&i64, &String)>,而不会出现关联类型的生命周期问题。它可以工作,但在我的项目中,Struct 拥有多个 Trait 的实现是没有意义的,所以我更喜欢使用关联类型。
感谢您的宝贵时间 :-)
【问题讨论】:
-
在你上面的第一个例子中,你不能使用
b.clone()来获取字符串的副本吗?它不太理想,但可能对您的情况有用!
标签: rust reference tuples lifetime borrow-checker