複製能力 (Abilities: Copy)
在 所有權與作用域章節中,我們看到基本值會被複製而非移動:將數字指定給新的變數後,兩個變數仍可使用。copy 能力正是啟用此行為的機制——雖然它內建於基本型別,但對自訂型別而言,這不是預設行為。Move 的設計目的是表達數位資產與資源,而可以自由複製的資源就不太像資源。因此,型別必須明確選擇允許複製:
public struct Copyable has copy {}
一旦型別具有 copy 能力,在原本會發生移動且仍需要原始值的位置,其值便會被複製——隱含地進行,不需要任何特殊語法。你可以使用 copy 關鍵字明確寫出複製操作:
let a = Copyable {};
// `a` is copied into `b` implicitly - both are usable afterwards.
let b = a;
// The `copy` keyword makes the copy explicit.
let c = copy a;
// `Copyable` does not have the `drop` ability, so every instance -
// `a`, `b`, and `c` - has to be used. Here, we unpack all of them.
let Copyable {} = a;
let Copyable {} = b;
let Copyable {} = c;
在上述範例中,a 會隱含地複製到 b——編譯器發現之後還會使用 a,因此複製該值而非移動它。接著,使用 copy 關鍵字將 a 明確複製到 c。完成三次指定後,會有三個彼此獨立的 Copyable 執行個體——每一個都必須分別處理。
請注意範例結尾的解構:Copyable 具有 copy,但沒有 drop,因此每個執行個體——包括每一份複製——都必須被使用,測試會解構這三個執行個體。複製值絕不會略過使用規則;它只會建立更多適用這些規則的值。
複製與丟棄 (Copying and Drop)
如範例所示,只有 copy 而沒有 drop 是相當不方便的組合:允許複製,但每個複本仍需要明確處理。這就是兩種能力幾乎總是一起出現的原因——實務上,可以輕易複製的值通常也可以安全丟棄。承載一般資料而非資產的型別,通常會同時宣告這兩種能力:
public struct Value has copy, drop {}
所有基本型別的行為都如同具有 copy 和 drop:它們在指定時會被複製,也能直接丟棄——所有這些處理都由編譯器管理。
複製並不是讓程式多個部分讀取同一個值的唯一方法。在 參考章節中,我們說明如何改為借用值,完全避免複製;以及解除參考運算子 * 如何將參考轉回複本,而這只允許用於具有 copy 能力的型別。
具有 copy 能力的型別 (Types with the copy Ability)
Move 中所有原生型別都具有 copy 能力,包括:
標準函式庫中定義的所有型別也都具有 copy 能力,包括:
如同 drop,容器型別只有在其內容可複製時才能複製:只有在原本允許複製 T 的情況下,vector<T> 才能被複製。
延伸閱讀 (Further Reading)
- Move 參考文件中的型別能力。