【发布时间】:2017-11-12 21:04:57
【问题描述】:
对于实现Clone 的任意结构,我希望有一个通用函数,它采用以下任一方式:
-
&MyStruct在这种情况下,它可以被函数有条件地克隆 -
MyStruct在这种情况下克隆是不必要的,因为它可以移动
我自己实现了这个:
use std::clone::Clone;
#[derive(Debug)]
struct MyStruct {
value: u64,
}
impl Clone for MyStruct {
fn clone(&self) -> Self {
println!("cloning {:?}", self);
MyStruct { value: self.value }
}
}
trait TraitInQuestion<T> {
fn clone_or_no_op(self) -> T;
}
impl TraitInQuestion<MyStruct> for MyStruct {
fn clone_or_no_op(self) -> MyStruct {
self
}
}
impl<'a> TraitInQuestion<MyStruct> for &'a MyStruct {
fn clone_or_no_op(self) -> MyStruct {
self.clone()
}
}
fn test<T: TraitInQuestion<MyStruct>>(t: T) {
let owned = t.clone_or_no_op();
}
fn main() {
let a = MyStruct { value: 8675309 };
println!("borrowing to be cloned");
test(&a);
println!("moving");
test(a);
}
输出如预期:
borrowing to be cloned
cloning MyStruct { value: 8675309 }
moving
这个功能是否已经通过实现Clone 派生出来了?如果没有,std::borrow::ToOwned 听起来像我想要的,但我无法让它工作:
use std::clone::Clone;
use std::borrow::Borrow;
#[derive(Debug)]
struct MyStruct {
value: u64,
}
impl Clone for MyStruct {
fn clone(&self) -> Self {
println!("cloning {:?}", self);
MyStruct { value: self.value }
}
}
fn test<T: ToOwned<Owned = MyStruct>>(a: T) {
let owned = a.to_owned();
}
fn main() {
let a = MyStruct { value: 8675309 };
println!("borrowing to be cloned");
test(&a);
println!("moving");
test(a);
}
编译器输出:
error[E0277]: the trait bound `MyStruct: std::borrow::Borrow<T>` is not satisfied
--> src/main.rs:16:1
|
16 | / fn test<T: ToOwned<Owned = MyStruct>>(a: T) {
17 | | let owned = a.to_owned();
18 | | }
| |_^ the trait `std::borrow::Borrow<T>` is not implemented for `MyStruct`
|
= help: consider adding a `where MyStruct: std::borrow::Borrow<T>` bound
= note: required by `std::borrow::ToOwned`
按照编译器的建议通过更改test:
fn test<T: ToOwned<Owned = MyStruct>>(a: T) -> ()
where
MyStruct: Borrow<T>,
{
let owned = a.to_owned();
}
以及由此产生的错误:
error[E0308]: mismatched types
--> src/main.rs:27:10
|
27 | test(&a);
| ^^ expected struct `MyStruct`, found &MyStruct
|
= note: expected type `MyStruct`
found type `&MyStruct`
如果我尝试为&MyStruct 实现ToOwned
impl<'a> ToOwned for &'a MyStruct {
type Owned = MyStruct;
fn to_owned(&self) -> Self::Owned {
self.clone()
}
}
我收到以下错误:
error[E0119]: conflicting implementations of trait `std::borrow::ToOwned` for type `&MyStruct`:
--> src/main.rs:16:1
|
16 | / impl<'a> ToOwned for &'a MyStruct {
17 | | type Owned = MyStruct;
18 | |
19 | | fn to_owned(&self) -> Self::Owned {
20 | | self.clone()
21 | | }
22 | | }
| |_^
|
= note: conflicting implementation in crate `alloc`
【问题讨论】:
-
你已经熟悉
Cow了吗? -
哦,我不知道
Cow.. 这就是我一直在寻找的东西,一定错过了。虽然,在某些情况下似乎没有必要将输入包装在枚举中(即Cow是动态调度,因为我的TraitInQuestion是静态调度,如果这个类比有意义的话)