Не в состоянии использовать протокол в качестве ключа в словаре в Swift
Я разрабатываю функциональность для двух подмножеств одного типа. например. фрукты. У меня есть два перечисления для фруктов, как показано ниже:
enum SourFruits: String {
case Grape, Orange, Lemon
}
enum SweetFruits: String {
case Watermelon, Banana, Apple
}
Чтобы использовать эти два как один тип в моей реализации, я использую протокол:
protocol Fruits {
}
extension SweetFruits: Fruits {
}
extension SourFruits: Fruits {
}
Теперь вот моя реализация выглядит так:
func doCommonOnFruit(fruit: Fruits) {
//Do common
}
func doSomeThingWithSourFruit(fruit: SourFruits) {
doCommonOnFruit(fruit)
// Do specific
}
func doSomeThingWithSweetFruit(fruit: SweetFruits) {
doCommonOnFruit(fruit)
// Do specific
}
Это работает нормально, но когда я пытаюсь добавить его на карту в качестве ключа:
let map: [Fruit : String] = [:]
Это подскажет мне ошибку говорит: Type 'Fruit' does not confirm to protocol 'Hashable'
, Моя карта должна содержать любые (сладкие или кислые фрукты в качестве ключа). Как этого добиться.
Я пытался реализовать Hashable
во фруктах, но это не сработало. Пожалуйста, помогите мне в этом.
2 ответа
Вы не можете использовать протокол здесь - протоколы на самом деле не какого-либо типа... это просто определение. то же самое может быть достигнуто через класс.
class Fruits : NSObject {
}
Теперь определите, подкласс фруктов. Вы можете перечислить как часть подкласса.
class SweetFruits: Fruits {
enum SweetFruits: String {
case Watermelon, Banana, Apple
}
}
class SourFruits: Fruits {
enum SourFruits: String {
case Grape, Orange, Lemon
}
}
в общем методе вы можете получить к нему доступ следующим образом...
func doCommonOnFruit(fruit: Fruits) {
if(fruit.isKind(of: SourFruits.classForCoder()))
{
}
if(fruit.isKind(of: SweetFruits.classForCoder()))
{
}
//Do common
}
func doSomeThingWithSourFruit(fruit: SourFruits) {
doCommonOnFruit(fruit: fruit)
// Do specific
}
func doSomeThingWithSweetFruit(fruit: SweetFruits) {
doCommonOnFruit(fruit: fruit)
// Do specific
}
// Вы можете напрямую использовать Enum с именем класса, как показано ниже.
func test()
{
let map: [Fruits : String] = [:]
let test = SourFruits.SourFruits.Grape
}
Если протокол 'Fruits' соответствует протоколу 'Hashable', его можно использовать только как общее ограничение, поскольку он имеет Self или требования к связанному типу.