Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lazy var: Cannot use mutating getter on immutable value

Tags:

swift

At the line, dateFormatter.string(from: date), the compiler says:

Cannot use mutating getter on immutable value: 'self' is immutable
Mark method 'mutating' to make 'self' mutable

struct viewModel {
    
    private lazy var dateFormatter = { () -> DateFormatter in
        let formatter = DateFormatter()
        formatter.dateFormat = "MM/dd/yyyy"
        return formatter
    }()
    
    var labelText: String? {
        let date = Date()
        return dateFormatter.string(from: date)
    }
}

I understand what is written in this link, but the above situation is probably different.

Does anyone know how to get around this problem?

like image 778
OutOnAWeekend Avatar asked May 24 '17 17:05

OutOnAWeekend


2 Answers

You need a mutating getter in order to perform mutations on self (such as accessing a lazy variable).

struct ViewModel {
    private lazy var dateFormatter = { () -> DateFormatter in
        let formatter = DateFormatter()
        formatter.dateFormat = "MM/dd/yyyy"
        return formatter
    }()

    var labelText: String? {
        mutating get {
            let date = Date()
            return dateFormatter.string(from: date)
        }
    }
}
like image 118
Alexander Avatar answered Sep 29 '22 21:09

Alexander


Accessing a lazy property on a struct mutates the struct to create the lazy property, same as if you were changing a var variable on that property.

So you are not allowed to use lazy var in any circumstance where re-assigning the var after init would not be allowed.

This is rather unintuitive, as using lazy var doesn't "feel" like it is mutating the struct after assignment. But when you think about it, that's exactly what's happening.

like image 30
pkamb Avatar answered Sep 29 '22 20:09

pkamb