Rust 在未实现复制特征时重构“克隆”?
考虑到我在评论中提到的限制,有没有办法摆脱Rust 在未实现复制特征时重构“克隆”?,rust,Rust,考虑到我在评论中提到的限制,有没有办法摆脱clone()?我真的很想知道在这种情况下是否可以使用借用,因为修改第三方函数签名是不可能的 // We should keep the "data" hidden from the consumer mod le_library { pub struct Foobar { data: Vec<i32> // Something that doesn't implement Copy } impl
clone()
?我真的很想知道在这种情况下是否可以使用借用,因为修改第三方函数签名是不可能的
// We should keep the "data" hidden from the consumer
mod le_library {
pub struct Foobar {
data: Vec<i32> // Something that doesn't implement Copy
}
impl Foobar {
pub fn new() -> Foobar {
Foobar {
data: vec![1, 2, 3],
}
}
pub fn foo(&self) -> String {
let i = third_party(self.data.clone()); // Refactor out clone?
format!("{}{}", "foo!", i)
}
}
// Can't change the signature, suppose this comes from a crate
pub fn third_party(data:Vec<i32>) -> i32 {
data[0]
}
}
use le_library::Foobar;
fn main() {
let foobar = Foobar::new();
let foo = foobar.foo();
let foo2 = foobar.foo();
println!("{}", foo);
println!("{}", foo2);
}
//我们应该对消费者隐藏“数据”
莫德勒乌图书馆{
pub结构Foobar{
数据:Vec//不实现复制的内容
}
impl Foobar{
pub fn new()->Foobar{
福巴{
数据:vec![1,2,3],
}
}
发布fn foo(&self)->字符串{
让我=第三方(self.data.clone());//重构克隆?
格式!(“{}{}”,“foo!”,i)
}
}
//无法更改签名,假设它来自板条箱
第三方发布(数据:Vec)->i32{
数据[0]
}
}
使用leu库::Foobar;
fn main(){
让foobar=foobar::new();
设foo=foobar.foo();
设foo2=foobar.foo();
println!(“{}”,foo);
println!(“{}”,foo2);
}
不,您无法在此处取消对
clone
的调用
这里的问题在于第三方库。由于现在编写了函数
第三方
,因此它确实可以使用&Vec
;它不需要所有权,因为它只是移出一个Copy
的值。但是,由于实现不在您的控制范围内,因此没有什么可以阻止维护函数的人员更改它以利用拥有Vec
的优势。如果允许重写提供的内存,那么无论它在做什么,都可能会更容易或需要更少的内存,函数编写器将为将来这样做敞开大门。如果不是这样的话,那么建议更改第三方函数的签名并同时依赖于clone
。不,您无法摆脱对clone
的调用
这里的问题在于第三方库。由于现在编写了函数第三方
,因此它确实可以使用&Vec
;它不需要所有权,因为它只是移出一个Copy
的值。但是,由于实现不在您的控制范围内,因此没有什么可以阻止维护函数的人员更改它以利用拥有Vec
的优势。如果允许重写提供的内存,那么无论它在做什么,都可能会更容易或需要更少的内存,函数编写器将为将来这样做敞开大门。如果不是这样的话,那么建议更改第三方函数的签名并同时依赖于clone
。只要您的foo()
方法接受&self
,这是不可能的,因为
pub fn third_party(data: Vec<i32>) -> i32
pub fn第三方(数据:Vec)->i32
签名是非常明确的:不管这个第三方
函数做什么,它的API声明它需要自己的Vec
实例。这就排除了使用任何形式的借用,而且因为foo()
通过引用接受self
,所以除了克隆之外,你真的什么都做不了
此外,据说这个第三方
是在没有任何奇怪的不安全黑客攻击的情况下编写的,因此可以很安全地假设传入它的Vec
最终被丢弃和释放。因此,在不克隆(通过复制内部指针)的情况下,不安全地创建原始Vec
的副本是不可能的-如果您这样做,您一定会在免费后得到使用
虽然您的问题没有说明这一点,但您希望保留数据的原始值这一事实是一种自然的假设。如果这个假设可以放宽,并且您实际上可以给出数据
实例,例如在内部用空向量替换它,那么您可以做以下几件事:
将foo(&self)
切换到foo(&mut self)
,然后您可以非常轻松地提取数据
,并将其替换为空向量
使用或存储数据。通过这种方式,您可以继续使用foo(&self)
,在您从单元格中提取值并将其替换为某个默认值时,需要进行一些运行时检查
但是,这两种方法都会导致丢失原始的Vec
。对于给定的第三方API,这是无法避免的
如果您仍然可以以某种方式影响此外部API,那么最好的解决方案是将其更改为接受&[i32]
,这可以通过借用从Vec
轻松获得。只要您的foo()
方法接受&self
,这是不可能的,因为
pub fn third_party(data: Vec<i32>) -> i32
pub fn第三方(数据:Vec)->i32
签名是非常明确的:不管这个第三方
函数做什么,它的API声明它需要自己的Vec
实例。这就排除了使用任何形式的借用,而且因为foo()
通过引用接受self
,所以除了克隆之外,你真的什么都做不了
此外,据说这个第三方
是在没有任何奇怪的不安全黑客攻击的情况下编写的,因此可以很安全地假设传入它的Vec
最终被丢弃和释放。因此,在不克隆(通过复制内部指针)的情况下,不安全地创建原始Vec
的副本是不可能的-如果您这样做,您一定会在免费后得到使用
虽然您的问题没有说明这一点,但您希望保留数据的原始值这一事实是一种自然的假设。如果这个假设可以放宽,你实际上