Swift 5. + - Как сделать класс хешируемым? - PullRequest
1 голос
/ 07 мая 2020

Я новичок в Swift, поэтому прошу прощения за очевидные недоразумения. Я попытался провести исследование без хорошего ответа.

У меня есть NavigationView со следующей итерацией

ForEach(listOfStuff, id: \.self)

listOfStuff определяется как структура, соответствующая Hashable, и все работает просто отлично.

Я хотел изменить структуру на класс и не могу понять, как сделать класс Hashable, чтобы \.self работал (он продолжает жаловаться, что класс должен быть Hashable)

Примеры старые или продолжают говорить о структурах. Я даже не знаю, смогу ли я использовать класс в ForEach? Что мне делать?

Спасибо

Ответы [ 2 ]

2 голосов
/ 07 мая 2020

Вот пример использования модели на основе классов в описанном сценарии использования. Протестировано с Xcode 11.4

class Stuff: Hashable, Equatable {
    static func == (lhs: Stuff, rhs: Stuff) -> Bool {
        lhs.title == rhs.title
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
    }

    var title: String = ""
}

struct StaffView: View {
    let listOfStaff: [Stuff]

    var body: some View {
        ScrollView {
            ForEach(listOfStaff, id: \.self) { stuff in
                Text(stuff.title)
            }
        }
    }
}
1 голос
/ 07 мая 2020

См. Принятие общих протоколов и Хэшируемая документация , оба из которых описывают процесс создания Hashable, как , описанный Asperi .

Но вам не обязательно делать все Hashable. Вы можете указать какое-либо свойство, по которому его можно идентифицировать, например

class Item {
    let id: UUID
    let string: String

    init(string: String) {
        self.id = UUID()
        self.string = string
    }
}

и

struct ContentView: View {
    let items: [Item]
    var body: some View {
        ScrollView {
            ForEach(items, id: \.id) { item in
                Text(item.string)
            }
        }
    }
}

Или, что еще лучше, сделайте его Identifiable, например

class Item: Identifiable {
    let id: UUID
    let string: String

    init(string: String) {
        self.id = UUID()
        self.string = string
    }
}

struct ContentView: View {
    let items: [Item]
    var body: some View {
        ScrollView {
            ForEach(items) { item in
                Text(item.string)
            }
        }
    }
}

Вы можете сделать это Hashable, если хотите, но Identifiable проще и достаточно для целей ForEach.

...