简体   繁体   中英

Make protocol conform to Hashable in Swift

I am trying to loop through an array which holds different types of exercises. In order to do so, I declared a protocol AnyExercise which can be hold by an array. I would like to add the Hashable protocol to my AnyExercise protocol. But I am getting the following error: Protocol 'AnyExercise' as a type cannot conform to 'Hashable'

I tried the following:

protocol AnyExercise {
var id: UUID {get}
var name: String {get}
var description: String {get}
func hash(into hasher: inout Hasher)
}

typealias Exercise = AnyExercise & Identifiable & Hashable

extension Break: Exercise {}
extension Pause: Exercise {}
extension Run: Exercise {}
extension Sprint: Exercise {}

Example struct implementation:

struct Sprint {
var id = UUID()
var name: String
var description: String

init() {
    self.name = "Sprint"
    self.description = "Sprint"
}

func hash(into hasher: inout Hasher) {
    hasher.combine(id)
    hasher.combine(name)
    hasher.combine(description)
}
}

Any ideas how to solve this? Or hold multiple different types in an array? Thanks.

although the following does not make the protocol AnyExercise Hashable , it does let you have an array with different types conforming to your AnyExercise protocol and usable in SwiftUI, using the id: \.id , as in the example code:

protocol AnyExercise {
    var id: UUID {get}
    var name: String {get}
    var description: String {get}
}

typealias Exercise = AnyExercise & Identifiable

extension Sprint: Exercise {}
extension Run: Exercise {}

struct Run {
    var id = UUID()
    var name: String
    var description: String
    
    init() {
        self.name = "Run"
        self.description = "Run"
    }
}

struct Sprint {
    var id = UUID()
    var name: String
    var description: String
    
    init() {
        self.name = "Sprint"
        self.description = "Sprint"
    }
}

struct ContentView: View {
    @State var results: [AnyExercise] = [Sprint(), Sprint(), Run()]
    
    var body: some View {
        ForEach(results, id: \.id) { item in
            Text(item.name)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM