[英]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>
當您派生Copy
和Clone
,特征總是分別將T
綁定為Copy
或Clone
。 有時,盡管您實際上並不需要T
來為整個結構體實現這些特征為Copy
或Clone
。
下面的結構就是一個例子。
#[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>
不需要T
為Copy
,它仍然限制它。
在這些情況下,您需要自己簡單地實現Copy
和Clone
。 只要結構的實際字段是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.