[英]How does Rust respect the Copy trait?
如果您使結構派生Copy
特征,則 Rust 將使y
在下面的代碼中作為x
的副本,而不是從x
移動到y
否則:
#[derive(Debug, Copy, Clone)]
struct Foo;
let x = Foo;
let y = x;
如果我在 C++ 中,我會說Copy
以某種方式使Foo
實現=
運算符,從而在右側復制整個 object 。
在Rust中,是不是簡單的在編譯器中實現為規則? 當編譯器找到let y=x
時,它只是檢查 Copy 特征是否派生並決定是復制還是移動?
我對 Rust 內部結構很感興趣,所以我可以更好地理解語言。 在教程中找不到此信息。
在Rust中,是不是簡單的在編譯器中實現為規則? 當編譯器找到 let y=x 時,它只是檢查 Copy 特征是否派生並決定是復制還是移動?
在運行時,沒有語義差異(盡管適用的優化可能會有所不同), move 和 copy 都只是一個memcopy
,並且在任何一種情況下,副本都可以被優化掉。
在編譯時,編譯確實知道Copy
/ !Copy
的區別:在x
將是!Copy
類型的情況下,賦值“消耗”變量,這意味着您以后不能使用它。
如果該項目是Copy
,那么它不是,你可以。
就是這樣。
是的,這是直接在編譯器中實現的。
它會影響任何會移動項目的情況,因此它也會影響將參數傳遞給函數或匹配表達式中的match
——基本上是任何涉及模式匹配的情況。 這樣一來,它就無法與在 C++ 中實現=
運算符相比。
Copy
trait 的定義在標准庫的源代碼中被標記為“lang”項。 編譯器知道用#[lang = "copy"]
標記的項目是決定一個類型是移動還是復制的特征。 編譯器還知道一些關於隱式Copy
類型的規則,例如僅包含Copy
項的閉包或元組。
如果您想深入了解這段代碼是如何編譯的,您可以查看 Playground 中的 MIR 表示。 在這個稍微簡化的版本中:
#[derive(Copy, Clone)]
struct Foo;
fn main() {
let x = Foo;
let y = x;
}
略微修剪的 MIR output 是:
bb0: {
StorageLive(_1);
_1 = const Scalar(<ZST>): Foo;
StorageLive(_2);
_2 = const Scalar(<ZST>): Foo;
StorageDead(_2);
StorageDead(_1);
return;
}
因此,在這種特定情況下,編譯器已確定Foo
是x
和y
(此處為_1
和_2
)的零大小類型(ZST),因此兩者都被分配了一個恆定的空值,因此沒有任何復制作為-這樣的。
要在操場上查看它, 請單擊此處,然后單擊“運行”按鈕右側的下拉三點按鈕中的 select“MIR”。 有關 MIR 的更多詳細信息,請查看rustc 開發指南。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.