使用AnyObject访问Swift字典成员

时间:2019-03-22 12:26:19

标签: swift dictionary syntax

我在理解如何正确地在Swift中解包时遇到了麻烦。情况如下:

我有这两节课:

class Alpha
{
  var val: Int

  init(x: Int)
  {
    val = x
  } 

  func doSomething() -> Int
  {
    // does stuff and returns an Int value
    return val
  }
}

和第二个类,它是第一个的子类

class Beta: Alpha
{
  var str: [String] = []

  override init(x: Int)
  {
    super.init(x)
  }

  func doSomething() -> String
  {
    // does stuff and returns a String
    return str
  }
}

到目前为止,这两个类都按预期工作。但是现在我想创建一个字典来存储这两个类对象中的几个。因此,我创建了一个类来管理字典并向其中添加项目。

class Gamma
{
  var myDict: [String:AnyObject] = [:]

  func addAlphaToDict(key: String, val: Int)
  {
    self.myDict[key] = Alpha(x: val).self
  }

  func addBetaToDict(key: String, val: Int)
  {
    self.myDict[key] = Beta(x: val).self
  }
}

这也可行,但是我认为可以有所改善。现在,当我尝试访问字典中的值时遇到的问题是

var foo = Gamma()

foo.addAlphaToDict(key: "blah", val: 45)
foo.addBetaToDict(key: "bluh", val: 23)

var result1 = (foo.myDict["blah"] as! Alpha).doSomething()

var result2 = (foo.myDict["bluh"] as! Beta).doSomething()

我发现这里的语法非常笨拙,即使可以正常工作,我仍觉得自己做错了。我是一位经验丰富的开发人员,但是刚刚开始使用Swift,因此我不确定某些事情。有更多具有Swift经验的人可以向我展示如何改进此代码,或者为我指明应该前进的方向吗?谢谢!

2 个答案:

答案 0 :(得分:2)

在这种情况下,您可以使用foreach($urls as $k => $val){ $urls[$k] = $val . "outline"; } 代替Alpha作为字典值。只需在需要时将其转换为AnyObject。应尽可能避免使用BetaAnyObject作为字典键。

但是,我不得不说这种方法是不好的。您不仅需要知道要传递给字典的密钥,还需要更清晰的逻辑来决定何时将密钥设为Any

答案 1 :(得分:1)

当您想要一个具有有限数量可能性的异构类型时,请迅速将具有关联值的enum设置为AnyAnyObject。然后,您可以使用switch以详尽且安全的方式恢复类型。

import UIKit
import PlaygroundSupport

enum DictionaryValues {
    case integer(Int), string(String)
}

let dictionary: [String: DictionaryValues] = ["a": .integer(1), "b": .string("xyz")]

for (key, value) in dictionary {
    switch value {
    case .integer(let number):
        print("Key \(key) is a number: \(number)")
    case .string(let text):
        print("Key \(key) is text: \(text)")
    }
}