2016-04-20 3 views
1

Я разрабатываю функциональность для двух подмножеств одного типа. например. фрукты. У меня есть два перечислений для фруктов, как показано ниже:Невозможно использовать протокол как ключ в словаре в 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 в Fruit, но это не сработало. Пожалуйста, помогите мне в этом.

+1

'Я пытался внедрить Hashable в Fruit, но это не сработало'. Вы должны нам, что вы пробовали. Реализация Hashable - это путь, возможно, вы сделали что-то не так. – Moritz

ответ

0

Если протокол «Фрукты» соответствует протоколу «Hashable», его можно использовать только в качестве общего ограничения, поскольку он имеет собственные или связанные требования типа.

0

Вы не можете использовать протокол здесь - протоколы на самом деле не имеют никакого типа ... только определение. То же самое можно достичь через класс.

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 
} 
Смежные вопросы