我知道我的词典将是<String,String>
或者它将是<String,NSNumber>
,有没有什么方法可以在声明时告诉Swift编译器,而不是声明<String,Any>
还是<String,AnyObject>
?
答案 0 :(得分:2)
enum Either<L, R> {
case left(L)
case right(R)
init(_ left: L) {
self = .left(left)
}
init(_ right: R) {
self = .right(right)
}
init?(_ any: Any) {
if let left = any as? L {
self = .left(left)
} else if let right = any as? R {
self = .right(right)
} else {
return nil
}
}
}
然后将您的字典声明为<String, Either<String, NSNumber>>
。
或者如果您喜欢硬编码类型:
enum StringOrNumber {
case string(String)
case number(NSNumber)
init(string: String) {
self = .string(string)
}
init(number: NSNumber) {
self = .number(number)
}
init?(any: Any) {
if let string = any as? String {
self = .string(string)
} else if let number = any as? NSNumber {
self = .number(number)
} else {
return nil
}
}
}
字典将是<String, StringOrNumber>
编辑:如果您的词典本身只能包含所有 String
或所有 NSNumber
值,类型应为Either<[String: String], [String: NSNumber]>
答案 1 :(得分:2)
您可以创建一个空协议,并使String和NSNumber符合它。
protocol StringOrNumber {}
extension String:StringOrNumber {}
extension NSNumber:StringOrNumber {}
显式添加Int,Float和Double
可能会有所帮助extension Int:StringOrNumber {}
extension Float:StringOrNumber {}
extension Double:StringOrNumber {}
然后你可以创建一个包含字符串和数字的字典
var dict:[String:StringOrNumber] = ["a":1, "b": 3.2,"c": "c"]
dict["d"] = "a string"
dict["e"] = 1.3
但你不能添加不是字符串或数字的东西
dict["f"] = Date() //error: Cannot assign value of type 'Date' to type 'StringOrNumber?'
答案 2 :(得分:0)
扩展user28434
的答案,你可以模仿C联盟类型的行为,因为它服务于&#34;或者&#34;情况最好,互相排斥。
联盟的Swift实现可能看起来很丑陋:
enum StringOrNum {
case a(String)
case b(NSNumber)
var a: String {
switch(self)
{
case .a(let stringValue): return stringValue
case .b(let nsnumberValue): return String(format:"%f", nsnumberValue.doubleValue)
}
}
var b: NSNumber {
switch(self)
{
case .a(let stringValue): if let intValue = Int(stringValue) {
return NSNumber(value: intValue)
}
else {
return NSNumber(value: 0) // default case
}
case .b(let nsnumberValue): return nsnumberValue
}
}
}
然后将字典声明为Dictionary<String, StringOrNum>
答案 3 :(得分:-1)
这会对你有帮助吗?
func myFoo<T>(dic: [String: T]) {
if dic["Key"] is String {
print("The value is String --> \(dic["Key"])")
}
if dic["Key"] is Int {
print("The value is Int --> \(dic["Key"])")
}
}
myFoo(dic: ["Key": 0])
myFoo(dic: ["Key": "Value"])