iTranslated by AI
The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🕊
[Swift] Why 'weak self' Is Not Needed (or Possible) in Structs
Key Takeaway
-
weak selfis not needed (and not possible) for structs.
Experiment
Let's define a class with a simple closure as follows:
struct Calculator {
let numA: Double
let numB: Double
let closure: (Double, Double) -> Void
init(numA: Double, numB: Double, closure: @escaping (Double, Double) -> Void) {
self.numA = numA
self.numB = numB
self.closure = closure
}
func calc() {
closure(numA, numB)
}
}
Now, let's try to write code where the closure uses a taxRate property held within the struct.
struct SampleStruct {
private let taxRate = 1.1
let numA: Double
let numB: Double
init(numA: Double, numB: Double) {
self.numA = numA
self.numB = numB
}
// ⭕️ This is possible
func getCalculator() -> Calculator {
Calculator(numA: numA, numB: numB) { numA, numB in
print("\((numA + numB) * self.taxRate)")
}
}
}
Since self is used in the closure processing, if you try to add [weak self] out of habit, the compiler will complain.
struct SampleStruct {
private let taxRate = 1.1
let numA: Double
let numB: Double
init(numA: Double, numB: Double) {
self.numA = numA
self.numB = numB
}
// ❌ This is not possible
func getCalculator() -> Calculator {
Calculator(numA: numA, numB: numB) { [weak self] numA, numB in // 'weak' may only be applied to class and class-bound protocol types, not 'SampleStruct'
guard let self = self else {
print("self is nil")
return
}
print("\((numA + numB) * self.taxRate)")
}
}
}
Let's look at the error message.
Error message:
'weak' may only be applied to class and class-bound protocol types
It seems that 'weak' cannot be used with structs.
Since structs are value types and not reference types like classes, this is actually expected behavior.
That's all.
Discussion