Created
June 8, 2023 11:13
-
-
Save cecilemuller/9282da43ecfbd07ce5a90d37f5726d18 to your computer and use it in GitHub Desktop.
Swift 5.9: Noncopyable struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Noncopyable struct: passed by reference | |
// and only one variable can hold the reference. | |
struct User: ~Copyable { | |
var name: String | |
// Read-only | |
func read() { | |
print(self.name) | |
// self.name = "BBBBB" // Error: 'self' is immutable | |
} | |
// Read-write | |
mutating func readWrite() { | |
print(self.name) | |
self.name = "CCCCC" | |
} | |
// Read-write, and doesn't return ownership afterwards | |
consuming func finalize() { | |
print(self.name) | |
self.name = "DDDDD" | |
} | |
} | |
// ERROR: Noncopyable parameter must specify its ownership | |
// func implicitUser(_ user: User) { | |
// print(self.name) | |
// } | |
// Read-only, temporary ownership | |
func borrowUser(_ user: borrowing User) { | |
print(user.name) | |
// user.name = "Hello" // Error: 'user' is a 'let' constant | |
} | |
// Read-write, permanent ownership | |
func consumeUser(_ user: consuming User) { | |
print(user.name) | |
user.name = "EEEEE" // OK | |
} | |
// --- Usage examples --- // | |
let user1 = User(name: "AAAAA") | |
print(user1.name) // OK | |
// Transfers the reference to `user2` | |
var user2 = user1 | |
// print(user1.name) // Error: 'user1' used after consume | |
print(user2.name) // OK | |
// `borrowing` temporarily transfers ownership during function call. | |
borrowUser(user2) | |
print(user2.name) // OK | |
borrowUser(user2) | |
print(user2.name) // OK | |
user2.read() | |
print(user2.name) // OK | |
user2.read() | |
print(user2.name) // OK | |
user2.readWrite() | |
print(user2.name) // OK | |
user2.readWrite() | |
print(user2.name) // OK | |
// `consuming` permanently transfers ownership. | |
// consumeUser(user2) | |
// print(user2.name) // Error: 'user2' used after consume | |
user2.finalize() | |
// print(user2.name) // Error: 'user2' used after consume | |
// user2.finalize() // Error: 'user2' consumed more than once |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment