gpt4 book ai didi

swift - 如何将类型为 Class 的值存储在类型为 [String :Class] in Swift? 的字典中

转载 作者:搜寻专家 更新时间:2023-10-30 22:29:34 25 4
gpt4 key购买 nike

我想在 [String:SomeClass] 类型的字典中存储一个更专业的类型。这是一些示例代码来说明我的问题(也可以在 https://swiftlang.ng.bluemix.net/#/repl/579756cf9966ba6275fc794a 上使用):

class Thing<T> {}

protocol Flavor {}

class Vanilla: Flavor {}

var dict = [String:Thing<Flavor>]()

dict["foo"] = Thing<Vanilla>()

它产生错误 ERROR at line 9, col 28: cannot assign value of type 'Thing<Vanilla>' to type 'Thing<Any>?' .

我试过转换 Thing<Vanilla>() as Thing<Flavor>但这会产生错误 cannot convert value of type 'Thing<Vanilla>' to type 'Thing<Flavor>' in coercion .

我还尝试将 Dictionary 定义为类型 [String:Thing<Any>]但这也没有改变任何东西。

如何创建不同的集合 Thing无需诉诸普通 [String:AnyObject]

我还应该提到类 Thing不是我定义的(事实上它是关于 BoltsSwift Task s),所以解决方案创建一个 Thing 的基类没有类型参数是行不通的。

最佳答案

A Thing<Vanilla>不是 Thing<Flavor> . Thing不是协变的。在 Swift 中没有办法表达 Thing是协变的。这是有充分理由的。如果您的要求在没有严格规则的情况下被允许,我将被允许编写以下代码:

func addElement(array: inout [Any], object: Any) {
array.append(object)
}

var intArray: [Int] = [1]
addElement(array: &intArray, object: "Stuff")

IntAny 的子类型, 所以如果 [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()))

类型橡皮擦的具体细节可能因您的底层类型而异。


顺便说一句:关于这个的诊断已经非常好。如果你试着调用我 addElement在 Xcode 9 上面,你会得到这个:

Cannot pass immutable value as inout argument: implicit conversion from '[Int]' to '[Any]' requires a temporary

这告诉你的是 Swift 愿意通过 [Int]你在哪里问[Any]作为数组的特例(尽管这种特殊处理并未扩展到其他泛型类型)。 但是它只会通过制作数组的临时(不可变)副本来允许它。 (这是另一个很难推断 Swift 性能的例子。在其他语言中看起来像“转换”的情况下,Swift 可能会制作副本。也可能不会。很难确定。)

关于swift - 如何将类型为 Class<Class Implementing Protocol> 的值存储在类型为 [String :Class<Protocol>] in Swift? 的字典中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38590548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com