【问题标题】:Why is the `Clone` trait not implemented for `fn(&T)`?为什么 `fn(&T)` 没有实现 `Clone` 特征?
【发布时间】:2016-01-07 10:47:38
【问题描述】:

以下代码不起作用,因为 Clone 特征未针对 fn(&u16) 类型实现:

#[derive(Clone)]
struct FStruct(fn(&u16));

fn fn1(x:&u16){
    println!("fn1 called! {:?}", x);
}

fn fn2(x:&u16){
    println!("fn2 called! {:?}", x);
}

fn main() {

    let d1 = 32u16;
    let d2 = 42u16;

    let x1 = FStruct(fn1);
    let mut x2 = FStruct(fn2);

    x1.0(&d1); x2.0(&d2);

    x2 = x1.clone();//error: the trait `core::clone::Clone` is not implemented for the type `fn(&u16)`

    x1.0(&d1); x2.0(&d2);
}

我当然可以自己实现:

impl Clone for FStruct{
    fn clone(&self) -> Self{
        unsafe{
            let mut t: FStruct = std::mem::uninitialized();
            std::ptr::copy_nonoverlapping(self, &mut t, 1);
            t      
        }
    }
}

但这有点烦人。 Rust 只允许为用户类型实现 Clone,所以我需要一个围绕 fn(&T) 的结构或枚举。

这个实现真的可以安全使用吗?为什么Clone默认不为fn(&T)实现?

【问题讨论】:

    标签: rust


    【解决方案1】:

    “为什么”很简单:issue 28229 直到Rust 1.21.0 才得到解决。从那个版本开始,你的代码就可以编译了。

    在此之前,由于历史的一个怪癖,fn 指针确实实现了Copy,即使它们没有实现Clone(尽管这显然是不可能的)。因此,您可以这样做:

    impl Clone for FStruct {
        fn clone(&self) -> Self {
            FStruct(self.0)
        }
    }
    

    哪个更安全,更容易理解。

    【讨论】:

    • ... 因此,如果您将fn(&i16) 传递给采用T: Copy 的函数,该函数继续尝试克隆它,您将获得“error: internal compiler error: Encountered error `Unimplemented` selecting `Binder(<fn(&i16) as core::clone::Clone>)` during trans”乐趣!
    猜你喜欢
    • 2017-12-05
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2012-08-04
    相关资源
    最近更新 更多