我正在尝试创建一个“转换”协议,如果字典的值实现了该协议,则字典可以遵循该协议。
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
我想做的甚至是可行的吗?我需要更改或添加什么才能使其正常工作?
更新
类型擦除似乎是一种“解决方案”。所以基本上,我需要做类似的事情:
struct AnyFoo<Fooable> { }
此时,我现在可以包装/擦除字典文字中的所有内容:
["a": AnyFoo(6.28), "b": AnyFoo(42), "c": AnyFoo("boo")].foo
以及将Dictionary的扩展扩展为Value为AnyFoo的Dictionary的扩展。这真的比将Dictionary的扩展限制为Value为String而只做以下事情更好吗?
["a": 6.28.foo, "b": 42.foo, "c": "boo".foo].foo
对于一个简单的“转换”情况,我不确定使用TypeErasure推迟通过包装程序进行转换而获得的收益,而不是仅在创建字典之前进行转换。较少实际键入(如在字符输入中)来执行后者。所以我什么都没得到。
除非我缺少任何东西,就我而言,我可能只会对容器元素进行向下转换(例如as? Fooable
),并执行日志错误之类的操作。