user1046037
user1046037

Reputation: 17735

Passing property type as parameter

Is there a way to pass the property to a function as a parameter ?

class Car {

    let doors : Int = 4
    let price : Int = 1000
}

Is there a way to pass the Car property as a type to a function ?

I would like to achieve the following:

func f1(car: Car, property: SomeType) {

    println(car.property)

}

let c1 = Car()

f1(c1, doors)
f1(c1, price)

Would closures help, if so how ?

Upvotes: 5

Views: 1109

Answers (3)

Rob
Rob

Reputation: 438467

As Bill Chan said, nowadays we would use keypaths:

func f1<Value>(car: Car, keyPath: KeyPath<Car, Value>) {
    print(car[keyPath: keyPath])
}

f1(car: car, keyPath: \.doors)

My original answer, using NSObject types, is below. But this key path approach is generally preferable, as it gives us compile-time validation of the key.


Back in the day, one would have used Objective-C key-value coding by subclassing from NSObject:

class Car: NSObject {
    @objc let doors: Int = 4
    @objc let price: Int = 1000
}

Then, the f1 function could be:

func f1(car: Car, key: String) {
    guard let value = car.value(forKey: key) else { return }
    print(value)
}

f1(car: car, key: "doors")

Upvotes: 5

Bill Chan
Bill Chan

Reputation: 3473

Solution with key path:

class Car {

    let doors : Int = 4
    let price : Int = 1000
}

func f1<T: CustomStringConvertible>(car: Car, property: KeyPath<Car, T>) {

    print(car[keyPath: property])

}

let c1 = Car()

f1(car: c1, property: \.doors)
f1(car: c1, property: \.price)

Upvotes: 2

rintaro
rintaro

Reputation: 51911

I'm not sure this is what you want, but using closure:

func f1<T>(car: Car, getter: Car -> T) {
    println(getter(car))
}

let c1 = Car()

f1(c1, {$0.doors})
f1(c1, {$0.price})

Upvotes: 9

Related Questions