Search code examples
swiftimmutabilitylazy-initialization

Lazy var initialization error "Cannot use mutating getter on immutable value"


I tried two ways of initializing a lazy var, one works, the other gets a compiler error.

  1. OK: var maxDiscount = MaxDiscount(); maxDiscount.maxDiscountPercent
  2. ERROR: MaxDiscount().maxDiscountPercent If maxDiscountPercent was a stored property rather than a lazy var both usages would work.

Simplified example:

struct MaxDiscount {
        lazy var maxDiscountPercent: Int = {
        print("Lazy var maxDiscountPercent initialized")
        return 256
    }()
    
}
// initializes lazy var without an error

var maxDiscount = MaxDiscount()
print("Max percent discount: ", maxDiscount.maxDiscountPercent)

// initializes lazy var with error:
// "Cannot use mutating getter on immutable value: function call returns immutable value"

var maxDiscountPercent = MaxDiscount().maxDiscountPercent
print("Max percent discount: ", maxDiscountPercent)

It's not clear to me why one usage is mutable and the other immutable.


Solution

  • When you write var maxDiscount, you declare a variable (mutable). You would have a constant (immutable) with let maxDiscount = MaxDiscount().

    Now with var maxDiscountPercent = MaxDiscount().maxDiscountPercent, MaxDiscount() is an anonymous constant and you can't do everything on it.

    Try let maxDiscount = MaxDiscount() and you will get the same type of error and an invitation to change let by var.