簡體   English   中英

Rust 如何尊重 Copy 特征?

[英]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;
    }

因此,在這種特定情況下,編譯器已確定Fooxy (此處為_1_2 )的零大小類型(ZST),因此兩者都被分配了一個恆定的空值,因此沒有任何復制作為-這樣的。

要在操場上查看它, 請單擊此處,然后單擊“運行”按鈕右側的下拉三點按鈕中的 select“MIR”。 有關 MIR 的更多詳細信息,請查看rustc 開發指南

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM