class Thing<T> {} protocol Flavor {} class Vanilla: Flavor {} var dict = [String:Thing<Flavor>]() dict["foo"] = Thing<Vanilla>()
它在第9行产生错误ERROR,第28行:不能指定类型’Thing< Vanilla>‘的值输入’Thing< Any>?’.
我已经尝试将Thing< Vanilla>()作为Thing< Flavor>但是产生的错误无法转换’Thing< Vanilla>‘类型的值输入’Thing< Flavor>‘在胁迫中.
我也尝试将Dictionary定义为类型[String:Thing< Any>],但这也没有改变任何东西.
如何在不诉诸普通[String:AnyObject]的情况下创建不同事物的集合?
我还要提一下,我没有定义类Thing(事实上它是关于BoltsSwift任务),因此在没有类型参数的情况下创建Thing基类的解决方案不起作用.
解决方法
func addElement(array: inout [Any],object: Any) { array.append(object) } var intArray: [Int] = [1] addElement(array: &intArray,object: "Stuff")
Int是Any的子类型,因此如果[Int]是[Any]的子类型,我可以使用此函数将字符串附加到int数组.这打破了类型系统.不要那样做.
根据您的具体情况,有两种解决方案.如果是值类型,则重新打包:
let thing = Thing<Vanilla>(value: Vanilla()) dict["foo"] = Thing(value: thing.value)
如果是引用类型,请将其装入type eraser.例如:
// struct unless you have to make this a class to fit into the system,// but then it may be a bit more complicated struct AnyThing { let _value: () -> Flavor var value: Flavor { return _value() } init<T: Flavor>(thing: Thing<T>) { _value = { return thing.value } } } var dict = [String:AnyThing]() dict["foo"] = AnyThing(thing: Thing<Vanilla>(value: Vanilla()))
橡皮擦类型的细节可能会有所不同,具体取决于您的基础类型.
顺便说一句:围绕这个的诊断已经相当不错了.如果你试图在Xcode 9中调用我的addElement,你得到这个:
Cannot pass immutable value as inout argument: implicit conversion from '[Int]' to '[Any]' requires a temporary
这告诉你的是,Swift愿意传递[Int],你要求[Any]作为Arrays的特例(尽管这种特殊处理并没有扩展到其他泛型类型).但它只允许通过制作数组的临时(不可变)副本. (这是另一个很难推理Swift性能的例子.在其他语言看起来像“cast”的情况下,Swift可能会复制.或者它可能没有.很难确定.)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。