我正在尝试解决与解析JSON相关的单独问题。在这个过程中,我遇到了Swift编译器,因为我希望它使用闭包模板参数为可选类型选择函数重载。
我还没有在他们关于这个主题的文档中看到任何明确的内容,但是并不是期望所有其他方面都相同,swiftc会在泛型函数中使用闭包参数的参数来选择正确的重载吗?
以下是我能提出的最简单的样本:
import Foundation
let os:NSString = "foo!"
let d:[String:AnyObject] = ["a": os]
struct Model {
var opt:String?
var basic:String = ""
}
func read<T>(source:AnyObject?, set:T -> ()) {
if let t:T = source as? T {
println("basic: read type: \(T.self) from value \(source)")
}
else {
println("failed to read basic type \(T.self) from value \(source)")
}
}
func read<T>(source:AnyObject?, set:T? -> ()) {
assert(false, "this is not called")
if let t:T? = source as? T? {
println("optional: read optional type: \(T.self) from value \(source)")
}
else {
println("failed to read optional type \(T.self) from value \(source)")
}
}
var m = Model()
println(m)
let raw: AnyObject? = d["a"]
struct Property<T> {
typealias V = T
var get:() -> T
var set:T -> ()
func doRead(d:[String:AnyObject]) {
read(d["a"], set)
}
}
let b = Property(get: { m.basic }, set: { v in m.basic = v })
b.doRead(d)
let o = Property(get: { m.opt }, set: { v in m.opt = v })
o.doRead(d)
根据内联注释,我预计第二个重载将用于可选类型,但事实并非如此。我错过了什么吗?
修改
请注意,编译器正在从属性构造中推断可选/非可选类型 - 它知道闭包是可选的,它只是不选择重载。我已经恢复了上面的一些原始日志代码,输出是:
basic:read type:Swift.String from value Optional(foo!)
无法读取基本类型Swift.Optional from value Optional(foo!)