Я пытаюсь создать протокол "преобразования", которому может соответствовать Словарь, если его значения реализуют указанный протокол.
import Foundation
protocol Fooable {
var foo:String { get }
}
extension Double:Fooable {
var foo:String { get { return "number" } }
}
extension Int:Fooable {
var foo:String { get { return "count" } }
}
extension String:Fooable {
var foo:String { get { return "name" } }
}
extension Dictionary:Fooable where Key == String, Value:Fooable {
var foo:String {
get {
var result = "["
self.keys.sorted().forEach { key in
result += key
result += ": "
result += self[key]!.foo
}
result += "]"
return result
}
}
}
["a": 6.28, "b": 42, "c": "boo"].foo
Проблема в том, что последняя строка считается неоднозначной:
error: type of expression is ambiguous without more context
["a": 6.28, "b": 42, "c": "boo"].foo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
То, что я пытаюсь сделать, даже выполнимо?Что мне нужно изменить или добавить, чтобы это работало?
ОБНОВЛЕНИЕ
Тип Erasure кажется одним из "решений".В общем, мне нужно сделать что-то вроде:
struct AnyFoo<Fooable> { }
Теперь я могу обернуть / стереть все в моем словаре:
["a": AnyFoo(6.28), "b": AnyFoo(42), "c": AnyFoo("boo")].foo
вместе с уточнением расширениясловаря для словаря, где значение равно AnyFoo.Действительно ли это лучше, чем просто ограничить расширение словаря для случаев, когда вместо него используется значение «Строка», и просто выполнить:
["a": 6.28.foo, "b": 42.foo, "c": "boo".foo].foo
Для простого случая «преобразования» я не уверен, что получу выгоду от использованияTypeErasure, чтобы отложить преобразование через оболочку, по сравнению с простым преобразованием перед созданием словаря.Менее фактический набор (как при вводе символов), чтобы сделать последнее.Так что я ничего не получил.
Если я что-то не упустил, для моего случая я, вероятно, просто пойду с понижением (например, as? Fooable
) для элементов контейнера и сделаю что-то вроде logошибки или что-то.