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 self is 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.

GitHubで編集を提案

Discussion