接受不同于getter类型的Swift下标setter';s返回值

接受不同于getter类型的Swift下标setter';s返回值,swift,swift-subscript,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) -> An

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

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 { ... }
}

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

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

您还可以定义自己的类型并使其符合
integerliteralcoverable
stringliteralcoverable
协议


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

您可以使用两种不同的
下标
实现,并禁用其中一种实现的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

我在这里遇到了一个类似的问题,我为我的变量使用了一个泛型类型,并在它的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 */

我对此表示怀疑。如果这对你来说很重要,但更可能的是,这不会飞起来,你需要一个不同的设计。(请注意,属性也不能有不同的setter和getter类型。)为什么不能为getter使用其他类型?getter可以先将值转换为字符串,然后再使用它们从容器中获取值。使用您用来输入值的密钥将值取出来更有意义。我正在包装一个现有的苹果API来实现这一点。-[objectForKeyedSubscript:]和-[setObject:forKeyedSubscript:]的Obj-C签名使用.thx作为答案的类型不同。你知道吗,swift 5有相同的解决方案吗?