为什么 swift 不使用没有类型约束的通用 return 参数推断出适当的重载函数?
Why doesn't swift infer the appropriate overload function with a generic return argument without a type constraint?
备注
Swift 变化很快,这个问题是关于:
Xcode 7, Swift 2.0
说明
我想实现一个通用的 return 参数。很多时候,我发现有必要实现一个可选的版本重载,这样我就可以访问底层类型并适当地处理它。这是一些制造的功能。 String的赋值只是作为复制的占位符:
func ambiguous<T>() -> T {
let thing = "asdf"
return thing as! T
}
func ambiguous<T>() -> T? {
return nil
}
现在,如果我们看一下实现:
// Fine
let a: String = ambiguous()
// Ambiguous
let b: String? = ambiguous()
这似乎很明显,因为您可以将类型 T
分配给类型 T?
的变量。因此,它难以推断是有道理的。问题是,有了类型约束,它突然起作用了。 (这可以是任何东西,我使用 Equatable
以便于复制。
func nonAmbiguous<T : Equatable>() -> T {
let thing: AnyObject = "asdf"
return thing as! T
}
func nonAmbiguous<T : Equatable>() -> T? {
return nil
}
现在,它按预期运行:
// Fine
let c: String = nonAmbiguous()
// Fine
let d: String? = nonAmbiguous()
注意,这也适用于其他类型:
func nonAmbiguous<T>() -> [T] {
let thing: AnyObject = ["asdf"]
return thing as! [T]
}
func nonAmbiguous<T>() -> [T]? {
return nil
}
// Fine
let e: [String] = nonAmbiguous()
// Fine
let d: [String]? = nonAmbiguous()
问题:
有没有办法让 return 通用参数通过可选性推断出适当的重载?
如果没有
这是语言功能还是某处的错误。如果是语言功能,请解释防止出现这种行为的潜在问题。
第一个例子是模棱两可的,因为 T
可以推断为 String
和 String?
.
第二个例子没有歧义,因为String
是Equatable
而String?
不是,所以T : Equatable
不能推断为String?
。
第三种情况没有歧义,因为[T]
不是
推断为 [String]?
.
备注:一般来说,Optional<Wrapped>
不符合Equatable
即使 Wrapped
与 Array<Element>
一样
不符合 Equatable
即使 Element
符合。
这是 Swift 当前类型系统的限制
以后的版本可能会改进,比较
来自 Swift 开发邮件列表。
备注
Swift 变化很快,这个问题是关于:
Xcode 7, Swift 2.0
说明
我想实现一个通用的 return 参数。很多时候,我发现有必要实现一个可选的版本重载,这样我就可以访问底层类型并适当地处理它。这是一些制造的功能。 String的赋值只是作为复制的占位符:
func ambiguous<T>() -> T {
let thing = "asdf"
return thing as! T
}
func ambiguous<T>() -> T? {
return nil
}
现在,如果我们看一下实现:
// Fine
let a: String = ambiguous()
// Ambiguous
let b: String? = ambiguous()
这似乎很明显,因为您可以将类型 T
分配给类型 T?
的变量。因此,它难以推断是有道理的。问题是,有了类型约束,它突然起作用了。 (这可以是任何东西,我使用 Equatable
以便于复制。
func nonAmbiguous<T : Equatable>() -> T {
let thing: AnyObject = "asdf"
return thing as! T
}
func nonAmbiguous<T : Equatable>() -> T? {
return nil
}
现在,它按预期运行:
// Fine
let c: String = nonAmbiguous()
// Fine
let d: String? = nonAmbiguous()
注意,这也适用于其他类型:
func nonAmbiguous<T>() -> [T] {
let thing: AnyObject = ["asdf"]
return thing as! [T]
}
func nonAmbiguous<T>() -> [T]? {
return nil
}
// Fine
let e: [String] = nonAmbiguous()
// Fine
let d: [String]? = nonAmbiguous()
问题:
有没有办法让 return 通用参数通过可选性推断出适当的重载?
如果没有
这是语言功能还是某处的错误。如果是语言功能,请解释防止出现这种行为的潜在问题。
第一个例子是模棱两可的,因为 T
可以推断为 String
和 String?
.
第二个例子没有歧义,因为String
是Equatable
而String?
不是,所以T : Equatable
不能推断为String?
。
第三种情况没有歧义,因为[T]
不是
推断为 [String]?
.
备注:一般来说,Optional<Wrapped>
不符合Equatable
即使 Wrapped
与 Array<Element>
一样
不符合 Equatable
即使 Element
符合。
这是 Swift 当前类型系统的限制
以后的版本可能会改进,比较
来自 Swift 开发邮件列表。