Swift下标setter接受与getter的返回值不同的类型

时间:2014-09-13 01:15:33

标签: swift swift-subscript

我有一个自定义集合,可以接收任何类型的值并将它们转换为字符串。例如:

collection["key"] = 10
let value = collection["key"] // value is a String

有办法做到这一点吗?我尝试实现两个下标方法,但Swift不支持只写下标。

subscript(key: String) -> String {
  get { ... }
}

// Doesn't compile
subscript(key: String) -> AnyObject {
  set { ... }
}

4 个答案:

答案 0 :(得分:1)

您可以使用两个不同的subscript实现,并为其中一个实现禁用getter:

subscript(key: String) -> String {
    get { return "howdy" } // put real implementation here
}
subscript(key: String) -> AnyObject {
    get { fatalError("Oooops") }
    set { }
}

然而,这仍然留下了如何在上下文中区分这两个subscript调用的问题。最好通过外部参数名称为它们提供不同的签名:

subscript(key: String) -> String {
    get { return "howdy" } // put real implementation here
}
subscript(# any: String) -> AnyObject {
    get { fatalError("Oooops") }
    set { }
}

以下是如何使用它:

let m = MyClass()
m[any:"thing"] = 1
println(m["thing"]) // "1", presumably

答案 1 :(得分:0)

定义下标以根据需要返回AnyObject(或Any),并在使用getter时将结果转换为String。您可能已经需要处理subscript返回一个可选项,因此强制只是提取所需值的所有部分。

if let value = collection["key"] as String { ... }
else {...}

答案 2 :(得分:0)

您还可以定义自己的类型,使其符合IntegerLiteralConvertibleStringLiteralConvertible协议。

从技术上讲,你也可以为String编写一个扩展名,使其符合IntegerLiteralConvertible,但这可能会让人感到困惑,因为它可以在整个项目中使用。

答案 3 :(得分:0)

我在这里遇到了类似的问题,我使用我的变量的泛型类型解决了它,并在其getter上返回我想要的类型。你可以尝试做这样的事情:

class StorageClass {
  private var _value: String?
  public var value: Any? {
    set {
      if let num = newValue as? Int {
        self._value = String(format: "%d",num)
      }
    }
    get {
      return self._value
    }
  }
}

通过这样做,可以执行以下操作:

var storage = StorageClass()
storage.value = 10 /* setting value as an Integer */
let aString = storage.value as! String /* receiving a String value back */