Home > Software design >  Pass struct as generic type and access that generic types properties
Pass struct as generic type and access that generic types properties

Time:08-13

I'm working on a Swift package where an option will be to pass in a generic type (Person) and then that GenericStruct can use properties on that type passed in. The issue obviously is that the generic T has no idea what's being passed in. Is there a way to define the property to access on the generic type T?

struct Person: Equatable {
    var name: String
    var height: Double
}

struct ContentView: View {
    @State private var james = Person(name: "James", height: 175.0)
    
    var body: some View {
        GenericStruct(person: $james)
    }
}

struct GenericStruct<T: Equatable>: View {
    @Binding var person: T
    
    var body: some View {
        Text(person.name)) // This line.
    }
}

I want to specifically pass in which property to access on Person when passing it to GenericStruct. The property won't always be name it could be anything I define within Person. For example:

GenericStruct(person: $james, use: Person.name)

CodePudding user response:

Isn't this exactly a protocol?

protocol NameProviding {
    var name: String { get }
}

struct GenericStruct<T: Equatable & NameProviding>: View { ... }

Or is there a more subtle part of the question?


The best way to do this is to pass a String Binding:

struct GenericStruct: View {
    @Binding var text: String
    
    var body: some View {
        Text(text)) // This line.
    }
}

GenericStruct(text: $james.name)

But it is possible with key paths. It's just a bit more awkward and less flexible in this particular case:

// Should be the syntax, but I haven't double-checked it.
struct GenericStruct<T: Equatable>: View {
    @Binding var person: T
    var use: KeyPath<T, String>
    
    var body: some View {
        Text(person[keyPath: use]))
    }
}

GenericStruct(person: $james, use: \.name)
  • Related