Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it correct to convert from computed property to lazy variable under constant struct?

I wanted to change my code to use lazy variable instead of Computed property.
this code works

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 10.0, height = 10.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point{
        get{
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
    }}
let shape = Rect()
print(shape.center)

But this code produces an error

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 10.0, height = 10.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    lazy var center = Point(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2)) 
}
let shape = Rect()
print(shape.center)  

I can fix the error if I changed let shape = Rect() to variable type var shape = Rect() OR when I change Rect to class instead of struct
What is wrong with my code and why does it give me error?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Notice that getting a lazy property potentially changes the struct value. Its state could change from "the lazy property has not been computed" to "the lazy property has been computed". This is why the getters of lazy properties are mutating.

A let constant does not allow its value to change, so you can’t use mutating members on it. vars do, so that’s why using a var makes your code compile.

Changing Rect to a class makes it a reference type. This means that the let constant shape stores a reference to an instance of Rect, and this reference cannot be changed (e.g. you can’t do shape = someOtherRect afterwards). However, the instance of Rect can still be changed (remember that the let constant is only storing a reference to it), and so getting a lazy property is fine on shape, when Rect is a class. Doing this will only potentially change the instance of Rect.

In my opinion, it is not appropriate to change Rect.center to a lazy property. After the first use of its getter, center will stay unchanged even if you change origin or size:

var shape = Rect()
print(shape.center)
shape.size = Size(width: 100, height: 100)
// now shape.center is incorrect!
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading