繁体   English   中英

Rust,Copy Trait 在使用泛型时不适用于类型

[英]Rust, Copy Trait not working with a type when it uses generic

Rust 不会编译以下内容:

#[derive(Copy, Clone)]
struct WhateverStruct<T> {
    field : T
}

trait WhateverStructTrait<T> {
    fn to(self) -> WhateverStruct<T>;
}
impl<T> WhateverStructTrait<T> for *mut WhateverStruct<T> {
    fn to(self) -> WhateverStruct<T> {
        unsafe {* self }
    }
}

fn test() {
    let x = WhateverStruct { field : 7u32 };
    let _y = x;
    let _z = x;
    println!("Copying is fine");
}

fn main() {
    test();
}

它抱怨不安全的{* self }部分说

*self具有类型WhateverStruct<T> ,它没有实现Copy特性

然而,它确实实现了复制特性。 测试功能没有错误。 如果您将struct WhateverStruct<T> { field : T }更改为struct WhateverStruct { field : u32 }并从其余代码中删除<T> ,则一切都可以编译并运行得很好。 所以 Rust 不喜欢泛型。

在这里你可以在操场上看到: https : //play.rust-lang.org/? version = stable & mode = debug & edition = 2018 & gist =5d5c3a0f0e6e0153ec286ce38f0f3a2d

这是一个错误吗? 有解决办法吗?

对于任何泛型类型Foo<T>当您派生CopyClone ,特征总是分别将T绑定为CopyClone 有时,尽管您实际上并不需要T来为整个结构体实现这些特征为CopyClone

下面的结构就是一个例子。

#[derive(Copy, Clone)]
struct Foo<T> {
    _marker: std::marker::PhantomData<T>,
}

如果我们查看派生生成的代码( cargo-expand用于该目的),我们会得到类似

use std::prelude::v1::*;
#[macro_use]
extern crate std;

struct Foo<T> {
    _marker: std::marker::PhantomData<T>,
}

#[automatically_derived]
#[allow(unused_qualifications)]
impl<T: ::core::marker::Copy> ::core::marker::Copy for Foo<T> {}

#[automatically_derived]
#[allow(unused_qualifications)]
impl<T: ::core::clone::Clone> ::core::clone::Clone for Foo<T> {
    #[inline]
    fn clone(&self) -> Foo<T> {
        match *self {
            Foo {
                _marker: ref __self_0_0,
            } => Foo {
                _marker: ::core::clone::Clone::clone(&(*__self_0_0)),
            },
        }
    }
}

只看Copy的实现(并稍微清理一下)它是

impl<T: Copy> Copy for Foo<T> {}

因此,即使Foo<T>不需要TCopy ,它仍然限制它。

在这些情况下,您需要自己简单地实现CopyClone 只要结构的实际字段是Copy ,就有一个相当简单的实现。

struct Foo<T> {
    _marker: std::marker::PhantomData<T>,
}

impl<T> Copy for Foo<T> {}

impl<T> Clone for Foo<T> {
    fn clone(&self) -> Self {
        *self
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM