Как написать расширение словаря, которое обрабатывает необязательные значения
Я пытаюсь реализовать 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
,
2 ответа
Вы могли бы сделать это с отражением. Не требует намного больше кода, чем у вас уже есть:
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()
Возвращает
foo = bar
let dictionary: [String : AnyObject?] = ["foo" : nil]
dictionary.someMethod()
Возвращает
foo = nil cannot be cast to `String`
let dictionary: [String : AnyObject?] = ["foo" : UIViewController()]
dictionary.someMethod()
Возвращает
foo = Optional(<UIViewController: 0x7fee7e819870>) cannot be cast to `String`
У меня нет проблем, когда я вставляю ':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")
}
}