[英]Pass multiple references in a tuple in Rust
I have a trait with some associated type, and some of its functions take as input a reference of that type:我有一些关联类型的特征,它的一些函数将这种类型的引用作为输入:
trait Trait {
type Value;
fn do_something(&self, value: &Self::Value);
}
In one structure that implements this trait, Value
is a tuple, because I need to pass multiple values to do_something
:在实现此特征的一个结构中,
Value
是一个元组,因为我需要将多个值传递给do_something
:
struct Struct {}
impl Trait for Struct {
type Value = (i64, String);
fn do_something(&self, (a, b): &(i64, String)) {
println!("{} {}", a, b);
}
}
However, when I then use Struct
in practice, I hit a wall.但是,当我在实践中使用
Struct
时,我碰壁了。 Either I do this:要么我这样做:
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
}
but then I lose ownership of any non- Copy
type in the tuple.但随后我失去了元组中任何非
Copy
类型的所有权。 Alternatively, I can do this:或者,我可以这样做:
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);
}
which works, but the syntax is extremely heavy.这有效,但语法非常繁重。
Does anyone have some idea of how I can accomplish what I want in a more concise way?有谁知道我如何以更简洁的方式完成我想要的事情? I tried to have
Struct::Value
be of type (&i64, &String)
, but then the borrow checker complains about needing a lifetime for those references, which I'd like to avoid if possible.我试图让
Struct::Value
的类型为(&i64, &String)
,但是借用检查器抱怨这些引用需要生命周期,如果可能的话,我想避免这种情况。
Another alternative I tried was to use a type parameter (so, Trait<Value>
) instead of an associated type.我尝试的另一种选择是使用类型参数(因此,
Trait<Value>
)而不是关联类型。 In that case, I can have Struct
implement Trait<(&i64, &String)>
without the lifetime issue I had with an associated type.在这种情况下,我可以让
Struct
实现Trait<(&i64, &String)>
,而不会出现关联类型的生命周期问题。 It works, but in my project it never makes sense for Struct
to have more than one implementation of Trait
, so I'd much prefer to use an associated type.它有效,但在我的项目中,
Struct
拥有多个Trait
实现从来没有意义,所以我更喜欢使用关联类型。
Thanks for your time:-)谢谢你的时间:-)
I tried to have
Struct::Value
be of type(&i64, &String)
, but then the borrow checker complains about needing a lifetime for those references, which I'd like to avoid if possible.我试图让
Struct::Value
的类型为(&i64, &String)
,但是借用检查器抱怨这些引用需要生命周期,如果可能的话,我想避免这种情况。
It's not possible to avoid lifetimes.不可能避免一生。 All references have lifetimes, some of which the compiler can infer for you and some of which you have to explicitly annotate yourself.
所有引用都有生命周期,其中一些是编译器可以为你推断的,而其中一些你必须自己显式地注释。 Note: the compiler isn't always right so sometimes you have to explicitly annotate lifetimes anyway despite the compiler's inferences.
注意:编译器并不总是正确的,所以有时尽管编译器的推论,你还是必须显式地注释生命周期。
In that case, I can have
Struct
implementTrait<(&i64, &String)>
without the lifetime issue I had with an associated type.在这种情况下,我可以让
Struct
实现Trait<(&i64, &String)>
,而不会出现关联类型的生命周期问题。
Right, because the lifetimes the compiler inferred for those references happened to work, but you shouldn't be afraid of explicitly annotating them yourself when you need to.是的,因为编译器为这些引用推断出的生命周期恰好可以工作,但是您不应该害怕在需要时自己显式注释它们。
It works, but in my project it never makes sense for
Struct
to have more than one implementation ofTrait
, so I'd much prefer to use an associated type.它有效,但在我的项目中,
Struct
拥有多个Trait
实现从来没有意义,所以我更喜欢使用关联类型。
Alright then let's use an associated type.好吧,让我们使用关联类型。 Here's the code with all the necessary lifetime annotations:
这是包含所有必要生命周期注释的代码:
trait Trait<'a> {
type Value;
fn do_something(&self, value: Self::Value);
}
struct Struct {}
impl<'a> Trait<'a> for Struct {
type Value = (&'a i64, &'a String);
fn do_something(&self, (a, b): Self::Value) {
println!("{} {}", a, b);
}
}
fn main() {
let a = 10;
let b = "foo".to_owned();
let s = Struct {};
s.do_something((&a, &b)); // compiles
println!("{}", b); // compiles
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.