Expressing Rust Move-Only Types in Swift
In Rust, types that don't implement Copy are considered to be move-only and can only be copied via Clone or other means.
In Swift, there's currently no notion of moving a value. Reassignments of a value result in an implicit copy. For class types or anything that contains a class member, this will increment the strong reference count.
There seems to be three approaches to this:
-
Retrofit a
Moveprotocol that gives automagical move semantics.Pros:
-
Doesn't require Swift users to rewrite any existing code.
-
Allows for
deiniton non-classtypes.
Cons:
- Wouldn't work in the context of generics. Implicit copying would still be the default there unless a generic type is specified as
Move. Rust's move-only types work in generics because all types are assumed to be move-only unless a generic type is specified asCopy.
-
-
Introduce a
Copyprotocol and assume move-only otherwise. Essentially, just copy Rust.Pros:
-
Allows for easier FFI when Swift types cross over into Rust-land.
-
Fine-grained control over move semantics types.
-
Works in the context of generics out-of-the-box.
Cons:
-
Results in significant added complexity, increasing the learning curve. Implicit copying helps keep Swift succinct and expressive.
-
Massive source compatibility break. Requires stdlib and Swift users to rewrite all implicit copies and opt into
Copywhere appropriate.
-
-
Introduce a special
Move<T>wrapper type that gives a type move semantics.Pros:
- Allows for basic move-only types.
Cons:
- Doesn't gain much. Really only makes existing code more verbose.