当前位置: 首页 > 面试题库 >

如何存储Class类型的值 在[String:Class类型的字典中]在Swift中?

萧宏峻
2023-03-14
问题内容

我想在[String:SomeClass]类型的Dictionary中存储一个更专业的类型。这是一些说明我的问题的示例代码(也可以在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定义为type,[String:Thing<Any>]但这也没有任何改变。

如何在Thing不求助于平原的情况下创建不同s 的集合[String:AnyObject]

我还应该提到该类Thing不是我定义的(实际上是关于BoltsSwift Task的),因此创建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")

Int是的子类型Any,因此如果[Int]是的子类型[Any],则可以使用此函数将字符串追加到int数组。这打破了类型系统。不要那样做

根据您的实际情况,有两种解决方案。如果是值类型,则将其重新打包:

let thing = Thing<Vanilla>(value: Vanilla())
dict["foo"] = Thing(value: thing.value)

如果是引用类型,请在其旁边加上类型橡皮擦。例如:

// 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可能会复制一个副本。或者可能不会。但是很难确定。)



 类似资料:
  • 问题内容: 我正在尝试创建一个字典变量,其值是两种类型之一。我的尝试的一个例子应该使这一点更清楚: 这引发了仅语法功能类型可以通用的编译器错误。我想知道是否有可能,我只是不知道正确的语法? 问题答案: 为此所需的工具是带有关联数据的枚举。 这样可以捕获“一个浮标或布尔对象”,并提供更好的文档记录和类型安全性。 要卸载数据,请使用switch语句: 使用switch语句可确保覆盖所有可能的类型,并防

  • 我想写一个行为几乎等同于Python字典的C++对象。C++的和提供了Python词典已经具备的一些功能,但缺少一个最重要的功能,即能够添加任意对象和类型。即使这是不可能的,您能在多大程度上实现Python字典的功能? 前面的几个问题(这里和这里)未能处理向字典中添加多个类型的问题。 我认为最好的解决方案是使用指针对数据进行重新解释,或者使用某种带有类型限制的运行时多态性?

  • 问题内容: 在Swift编程语言中,它说“一个数组在一个有序列表中存储相同类型的多个值”。但是我发现您可以在数组中存储多种类型的值。描述不正确吗? 例如 问题答案: 来自REPL 您可以看到的是,这是或 发生的事情是提供了将数字和布尔值转换为的能力。需要编译代码时,编译器将执行转换。 因此,它们现在具有的通用类型,因此可以推断为 没有,您的代码将无法在REPL中编译。 但是你可以做到 因为它们具有

  • 问题内容: 我需要在Django模型中存储一些数据。这些数据并不等于模型的所有实例。 最初,我考虑过将模型子类化,但是我试图保持应用程序的灵活性。如果使用子类,则每次需要新的对象时都需要创建一个整个类,这是不好的。我还将最终得到很多子类,仅用于存储一对额外的字段。 我真的觉得词典是最好的方法,但是Django文档中没有关于在Django模型中存储词典的内容(或者我找不到它)。 有什么线索吗? 问题

  • 问题内容: 我想在一个程序包中打印所有的类名,并在每个程序包中打印相应的属性及其数据类型。 在一个代码中,我能够以字符串形式获取类名。在另一个代码中,我可以使用以下方法获取属性及其数据类型 但是我想合并两个代码。由于在第一个代码中我以字符串的形式获得了类名,我无法使用,因为这里是类型。 因此,我需要一种将“ 类名”从类型转换为类型的方法。 我试过了,但是没有用。 问题答案: 确保是完全合格的类名,

  • 问题内容: 我需要将字典保存在模型字段中。我怎么做? 例如,我有此代码: 我应该为“ bill_products =“写什么,以便从我的产品模型到此帐单保存一些随机产品? 这是账单的模型说明: 以及产品的型号说明: 如果还有什么我要补充的请发表评论。谢谢! 问题答案: 我刚刚发现了django-jsonfield软件包,该软件包 是可重用的Django字段,可让您在模型中存储经过验证的JSON。