首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建一个泛型变量字典

创建一个泛型变量字典
EN

Stack Overflow用户
提问于 2019-05-29 00:55:25
回答 3查看 240关注 0票数 0

我正在寻找一种将泛型子类存储在字典中的方法,但我遇到了问题。

在下面的示例中,我试图创建一个对象字典,其中我知道它将子类为Entity<T>。我正在成功地将子类FloatEntityStringEntity的单个实例存储在Entity类型var中,但是当我试图将相同的实例存储在类型为Dictionary<String, Entity>的字典中时,会得到一个错误。

代码语言:javascript
复制
class Entity<T> {
    var _value: T
    var value: T { get { return _value } set {_value = newValue}}

    init (defaultValue: T) {
        _value = defaultValue
    }
}

class FloatEntity: Entity<Float> {
}

class StringEntity: Entity<String> {
}

func run () {
    let variable1: Entity = FloatEntity (defaultValue: 1)
    let variable2: Entity = StringEntity (defaultValue: "")
    var dictionary: Dictionary<String, Entity> = [
        "One": FloatEntity (defaultValue: 1),
        "Two": StringEntity (defaultValue: ""),
    ]
    print (variable1)
    print (variable2)
    print (dictionary)
}

错误:

无法将“FloatEntitiy”类型的值转换为预期的字典值类型“实体”

有人能建议我如何使用字典来存储这样的仿制药吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-29 01:18:51

variable1variable2不是Entity类型,而是实际上是Entity<Float>Entity<String>这两个不相关的类型。使用protocol将它们联合起来:

代码语言:javascript
复制
protocol EntityProtocol { }

class Entity<T> : EntityProtocol {
    var _value: T
    var value: T { get { return _value } set {_value = newValue}}

    init (defaultValue: T) {
        _value = defaultValue
    }
}

class FloatEntity: Entity<Float> {
}

class StringEntity: Entity<String> {
}

func run () {
    let variable1: Entity = FloatEntity (defaultValue: 1)
    let variable2: Entity = StringEntity (defaultValue: "")
    var dictionary: Dictionary<String, EntityProtocol> = [
        "One": FloatEntity (defaultValue: 1),
        "Two": StringEntity (defaultValue: ""),
    ]
    print (variable1)
    print (variable2)
    print (dictionary)
}
票数 2
EN

Stack Overflow用户

发布于 2019-05-29 01:35:37

从您到目前为止所提供的信息来看,这看起来不像是一个泛型的好使用。如果要将值存储在字典中,其中每个值可能是字符串或浮点数,则听起来更像是带关联值的枚举(这是操场代码):

代码语言:javascript
复制
enum StringOrFloat {
    case string(String)
    case float(Float)
}
let v1 = StringOrFloat.string("meaning of life")
let v2 = StringOrFloat.float(42)
var d = Dictionary<String,StringOrFloat>()
d["hey"] = v1
d["ho"] = v2

这里有一种提取值的方法:

代码语言:javascript
复制
if let val = d["hey"] {
    switch val {
    case .string(let s):
        print("it is a string, namely", s)
    case .float(let f):
        print("it is a float, namely", f)
    }
}
票数 1
EN

Stack Overflow用户

发布于 2019-05-29 01:16:58

Swift泛型是不变的,因此Entity<B>不是Entity<A>的子类,即使B是A的子类,所以不能使用字典中Entity的超类存储相同的类型。

您可以通过使用AnyObject作为字典值来实现您想要的结果,例如使用以下代码:-

代码语言:javascript
复制
var dictionary: Dictionary<String, AnyObject> = [
  "One": FloatEntity (defaultValue: 1),
  "Two": FloatEntity (defaultValue: 2),
]

不过,我不认为你能从中提取一个类型删除的Entity (很高兴被纠正)。但你可以这样做:-

代码语言:javascript
复制
let v = dictionary["One"]
if let v1 = v as? FloatEntity
{
  ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56351768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档