我有一个自定义集合,可以接收任何类型的值并将它们转换为字符串。例如:
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 { ... }
}
答案 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)
您还可以定义自己的类型,使其符合IntegerLiteralConvertible
和StringLiteralConvertible
协议。
从技术上讲,你也可以为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 */