如何编写处理可选值的字典扩展
How to write Dictionary extension that handles optional values
我正在尝试实现 Dictionary
扩展,我想处理可选值。但是无论我做什么,如果我在 [String: String?]
字典上使用我的方法,它都无法选择性地绑定值。你如何编写一个字典的扩展来优雅地处理可选值?
考虑以下扩展:
extension Dictionary {
func someMethod() {
for (key, value) in self {
if let valueString = value as? String {
println(" \(key) = \(valueString)")
} else {
println(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}
所以考虑下面的代码:
let dictionary: [String: AnyObject?] = ["foo": "bar"]
dictionary.someMethod()
它奇怪地报告
foo = Optional(bar) cannot be cast to `String`
我可以编写一个非扩展方法来处理具有可选值的字典参数,但不知道如何将其作为 Dictionary
的扩展。
插入“:String?”时没有问题就在 valueString 之后,如下所示:
extension Dictionary {
func someMethod() -> Bool {
for (key, value) in self {
if let valueString:String? = value as? String {
println(" \(key) = \(valueString)")
} else {
println(" \(key) = \(value) cannot be cast to `String`")
return false
}
}
return true
}
}
func doSomething() {
let dictionary: [String: AnyObject?] = ["foo": "bar"]
if dictionary.someMethod() {
println("no problems")
} else {
println("casting issues")
}
}
你可以通过反思来做到这一点。不需要比您已有的更多的代码:
extension Dictionary
{
func someMethod()
{
for (key, value) in self
{
var valueRef = _reflect(value)
while valueRef.disposition == .Optional && valueRef.count > 0 && valueRef[0].0 == "Some"
{
valueRef = valueRef[0].1
}
if let valueString: String = valueRef.value as? String
{
print(" \(key) = \(valueString)")
}
else
{
print(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}
let dictionary: [String : AnyObject?] = ["foo" : "bar"]
dictionary.someMethod()
Returns
foo = bar
let dictionary: [String : AnyObject?] = ["foo" : nil]
dictionary.someMethod()
Returns
foo = nil cannot be cast to `String`
let dictionary: [String : AnyObject?] = ["foo" : UIViewController()]
dictionary.someMethod()
Returns
foo = Optional(<UIViewController: 0x7fee7e819870>) cannot be cast to `String`
我正在尝试实现 Dictionary
扩展,我想处理可选值。但是无论我做什么,如果我在 [String: String?]
字典上使用我的方法,它都无法选择性地绑定值。你如何编写一个字典的扩展来优雅地处理可选值?
考虑以下扩展:
extension Dictionary {
func someMethod() {
for (key, value) in self {
if let valueString = value as? String {
println(" \(key) = \(valueString)")
} else {
println(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}
所以考虑下面的代码:
let dictionary: [String: AnyObject?] = ["foo": "bar"]
dictionary.someMethod()
它奇怪地报告
foo = Optional(bar) cannot be cast to `String`
我可以编写一个非扩展方法来处理具有可选值的字典参数,但不知道如何将其作为 Dictionary
的扩展。
插入“:String?”时没有问题就在 valueString 之后,如下所示:
extension Dictionary {
func someMethod() -> Bool {
for (key, value) in self {
if let valueString:String? = value as? String {
println(" \(key) = \(valueString)")
} else {
println(" \(key) = \(value) cannot be cast to `String`")
return false
}
}
return true
}
}
func doSomething() {
let dictionary: [String: AnyObject?] = ["foo": "bar"]
if dictionary.someMethod() {
println("no problems")
} else {
println("casting issues")
}
}
你可以通过反思来做到这一点。不需要比您已有的更多的代码:
extension Dictionary
{
func someMethod()
{
for (key, value) in self
{
var valueRef = _reflect(value)
while valueRef.disposition == .Optional && valueRef.count > 0 && valueRef[0].0 == "Some"
{
valueRef = valueRef[0].1
}
if let valueString: String = valueRef.value as? String
{
print(" \(key) = \(valueString)")
}
else
{
print(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}
let dictionary: [String : AnyObject?] = ["foo" : "bar"]
dictionary.someMethod()
Returns
foo = bar
let dictionary: [String : AnyObject?] = ["foo" : nil]
dictionary.someMethod()
Returns
foo = nil cannot be cast to `String`
let dictionary: [String : AnyObject?] = ["foo" : UIViewController()]
dictionary.someMethod()
Returns
foo = Optional(<UIViewController: 0x7fee7e819870>) cannot be cast to `String`