对于任意实现了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()
}
}
I get the following error:
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
了吗? - ShepmasterCow
..这正是我在寻找的,一定是错过了。虽然,在某些情况下,将输入包装在枚举类型中似乎是不必要的(即Cow
与动态分派相对应,就像我的TraitInQuestion
与静态分派相对应一样,如果这个比喻说得通的话)。 - 10101