Swift 带可选值的字典下标
Swift dictionary subscript with optional values
亲爱的,
这是我的可在操场上测试的代码:
import Foundation
import UIKit
enum Error : Swift.Error, LocalizedError {
case failedTypeCastingUITableViewCell(name: String, type: Any.Type, reuseIdentifier: String?)
var domain: String {
return ""
}
var code: Int {
return 0
}
var nserror : NSError {
return NSError(domain: self.domain,
code: self.code,
userInfo: self.userInfo)
}
// var userInfo : [String: Any]? {
// var userInfo : [String: Any] = [:]
//
// switch self {
// case .failedTypeCastingUITableViewCell(let name, let type, let reuseIdentifier):
// userInfo = [
// "param_name": name
// ,"param_type": "\(type)"
// ,"param_identifier": reuseIdentifier
// ]
// return userInfo
// }
// }
var userInfo : [String: Any]? {
var userInfo : [String: Any] = [:]
switch self {
case .failedTypeCastingUITableViewCell(let name, let type, let reuseIdentifier):
userInfo = [
"param_name": name
,"param_type": "\(type)"
]
userInfo["param_identifier"] = reuseIdentifier
return userInfo
}
}
}
print(Error.failedTypeCastingUITableViewCell(name: "", type: UITableViewCell.self, reuseIdentifier: nil).userInfo)
这是我从打印中得到的结果,也是我想通过注释代码实现的结果:
Optional(["param_name": "", "param_type": "UITableViewCell"])
这是我从注释代码中得到的结果:
Optional(["param_identifier": nil, "param_type": "UITableViewCell", "param_name": ""])
我知道它必须以这种方式工作,但我的问题是我可以通过某种方式摆脱它吗? IE。自定义初始化?自定义下标?
是的!只是不要为那个下标写任何东西,当你试图访问那个下标时,它会自动 return nil.
示例:
myDict: [String : Any] = [
"key1" : 1,
"key2" : 2
]
let emptySubscript = myDict["key3"] // this will be nil
给出具体示例,这当然是可能的,并且有多种方式。
一种方法是使用 key/value 对,并过滤掉 nil:
let kv = [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
].filter{ != nil}.map{([=10=], !)} // <== this is your magic line
userInfo = Dictionary(uniqueKeysWithValues: kv)
另一种方法是 reduce
:
userInfo = [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
]
.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
为了提高可读性,您可以将其提取到扩展名中:
extension Dictionary {
init<S>(uniqueKeysWithNonNilValues seq: S)
where S : Sequence, S.Element == (Key, Value?) {
self = seq.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
}
}
然后调用代码会非常好 IMO:
userInfo = Dictionary(uniqueKeysWithNonNilValues: [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
])
但我们可以将它推得更接近您建议的语法,也许这样更好,因为它再次感觉像字典:
extension Dictionary {
init(withNonNilValues seq: KeyValuePairs<Key, Value?>) {
self = seq.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
}
}
userInfo = Dictionary(withNonNilValues: [
"param_name": name,
"param_type": "\(type)",
"param_identifier": reuseIdentifier,
])
亲爱的,
这是我的可在操场上测试的代码:
import Foundation
import UIKit
enum Error : Swift.Error, LocalizedError {
case failedTypeCastingUITableViewCell(name: String, type: Any.Type, reuseIdentifier: String?)
var domain: String {
return ""
}
var code: Int {
return 0
}
var nserror : NSError {
return NSError(domain: self.domain,
code: self.code,
userInfo: self.userInfo)
}
// var userInfo : [String: Any]? {
// var userInfo : [String: Any] = [:]
//
// switch self {
// case .failedTypeCastingUITableViewCell(let name, let type, let reuseIdentifier):
// userInfo = [
// "param_name": name
// ,"param_type": "\(type)"
// ,"param_identifier": reuseIdentifier
// ]
// return userInfo
// }
// }
var userInfo : [String: Any]? {
var userInfo : [String: Any] = [:]
switch self {
case .failedTypeCastingUITableViewCell(let name, let type, let reuseIdentifier):
userInfo = [
"param_name": name
,"param_type": "\(type)"
]
userInfo["param_identifier"] = reuseIdentifier
return userInfo
}
}
}
print(Error.failedTypeCastingUITableViewCell(name: "", type: UITableViewCell.self, reuseIdentifier: nil).userInfo)
这是我从打印中得到的结果,也是我想通过注释代码实现的结果:
Optional(["param_name": "", "param_type": "UITableViewCell"])
这是我从注释代码中得到的结果:
Optional(["param_identifier": nil, "param_type": "UITableViewCell", "param_name": ""])
我知道它必须以这种方式工作,但我的问题是我可以通过某种方式摆脱它吗? IE。自定义初始化?自定义下标?
是的!只是不要为那个下标写任何东西,当你试图访问那个下标时,它会自动 return nil.
示例:
myDict: [String : Any] = [
"key1" : 1,
"key2" : 2
]
let emptySubscript = myDict["key3"] // this will be nil
给出具体示例,这当然是可能的,并且有多种方式。
一种方法是使用 key/value 对,并过滤掉 nil:
let kv = [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
].filter{ != nil}.map{([=10=], !)} // <== this is your magic line
userInfo = Dictionary(uniqueKeysWithValues: kv)
另一种方法是 reduce
:
userInfo = [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
]
.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
为了提高可读性,您可以将其提取到扩展名中:
extension Dictionary {
init<S>(uniqueKeysWithNonNilValues seq: S)
where S : Sequence, S.Element == (Key, Value?) {
self = seq.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
}
}
然后调用代码会非常好 IMO:
userInfo = Dictionary(uniqueKeysWithNonNilValues: [
("param_name", name),
("param_type", "\(type)"),
("param_identifier", reuseIdentifier)
])
但我们可以将它推得更接近您建议的语法,也许这样更好,因为它再次感觉像字典:
extension Dictionary {
init(withNonNilValues seq: KeyValuePairs<Key, Value?>) {
self = seq.reduce(into: [:]) { (d, kv) in d[kv.0] = kv.1 }
}
}
userInfo = Dictionary(withNonNilValues: [
"param_name": name,
"param_type": "\(type)",
"param_identifier": reuseIdentifier,
])