Dynamic member lookup using KeyPath

Hi,

Overview

I have a doubt regarding dynamicMemberLookup

When I compile the code I get the error Cannot assign to property: 'car' is immutable

Questions

  1. Why do I get the error When I compile the code I get the error Cannot assign to property: 'car' is immutable
  2. How can I fix it?

Code

@dynamicMemberLookup
struct Car {
    
    var price = 1000
    var engine: Engine
    
    subscript <T>(dynamicMember keyPath: WritableKeyPath<Engine, T>) -> T {
        engine[keyPath: keyPath]
    }
    
}
struct Engine {
    var cylinders: Int
    var horsepower: Int
}

var engine = Engine(cylinders: 4, horsepower: 200)
var car = Car(engine: engine)

car.engine.cylinders = 6
car.cylinders = 6 //Error: Cannot assign to property: 'car' is immutable

The subscript needs to define a setter in addition to the getter i.e.:

    subscript <T>(dynamicMember keyPath: WritableKeyPath<Engine, T>) -> T {
        get { engine[keyPath: keyPath] }
        set { engine[keyPath: keyPath] = newValue }
    }
1 Like

Thank you so much @dnadoba !

I feel so dumb for missing the setter, thanks a lot! I was breaking my head over this.

I must admit that the error Cannot assign to property: 'car' is immutable is very confusing. car is mutable but the property cylinders isn't mutable instead. Do you mind filling an issue?

5 Likes

I have created a bug, let me know if it is clear or if you would like me to add more details:

4 Likes

The description is very clear, thank you!

1 Like