我确实遇到了重载泛型方法的问题。考虑这个例子:
class Foo {
func foo<T>(v: T) {
println("foo<T>(v: T)")
}
func foo<T>(x: Int, v: T) {
println("foo<T>(x: Int, v: T)")
}
}
let foo = Foo()
foo.foo("")
foo.foo(1, "")
foo.foo(x: 1, "")
foo.foo(x: 1, v: "")
这会将以下内容输出到控制台:
foo(v:T)
foo(v:T)
foo(v:T)
foo(v:T)
也就是说,无论如何,只从重载决策中选择方法foo<T>(v: T)
。注意:编译器将元组(:Int, :String)
传递给第一个方法,而不是调用第二个方法。
这是预期的行为吗?
嗯,我怀疑:我确实承认类型参数可以包含一个元组,但是我认为函数foo<T>(x: Int, v: T)
是一个更好的匹配。
不幸的是,我无法找到解决方法。通用方法foo<T>(v: T)
似乎通过传递元组来适应所有内容 - 无论存在什么其他重载。
在Xcode V6.1.1(6A2008a)中,与方法(绑定到特定类型的函数)相反,重载的函数按预期解析:
请考虑以下代码段:
func foo<T>(o: T) {
println("foo<T>(:T), \(o)")
}
func foo<T>(x: Int, o: T) {
println("foo<T>(:Int, :T), \(x), \(o)")
}
foo(1)
foo(1, "a")
这会将以下内容输出到控制台:
foo(:T),1
foo(:Int,:T),1,a
这让我相信这是编译器中的一个问题。我提交了一份错误报告。
答案 0 :(得分:1)
尝试在第一个参数之前删除“x:”,如:
foo.foo(1, v: "")
<强>已更新强>
对于方法,默认行为是:
具体来说,默认情况下,Swift在方法中为第一个参数名称提供一个本地参数名称,并默认为第二个和后续参数名称提供本地和外部参数名称。
功能:
如果希望函数用户在调用函数时提供参数名称,请为本地参数名称定义每个参数的外部参数名称。您在它支持的本地参数名称之前编写外部参数名称,用空格分隔:...
文件还在功能中说:
如果为参数提供外部参数名称,则在调用该函数时必须始终使用该外部名称。
看起来这对于方法来说是正确的,这就是foo.foo(1, v: "")
仅适用于方法的原因,因为有一个外部参数名称,你必须使用它。
答案 1 :(得分:1)
一些可能的修复:
当然,您未在示例中尝试的一个案例不是命名x
,而是命名v
:
foo.foo(1, v: "") // prints foo<T>(x: Int, v: T)
或者,如果你抛弃命名参数v
:
class Foo {
func foo<T>(v: T) {
println("foo<T>(v: T)")
}
func foo<T>(x: Int, _ v: T) {
println("foo<T>(x: Int, v: T)")
}
}
let foo = Foo()
foo.foo("") // prints foo<T>(v: T)
foo.foo(1, "") // prints foo<T>(x: Int, v: T)
foo.foo(1, "") // prints foo<T>(x: Int, v: T)
幽默地说,这翻了一个之前有效的电话来做相反的事情:
foo.foo(1, v: "") // prints foo<T>(v: T)
或者,您可以为所有
命令参数名称。class Foo {
func foo<T>(#v: T) {
println("foo<T>(v: T)")
}
func foo<T>(#x: Int, v: T) {
println("foo<T>(x: Int, v: T)")
}
}
let foo = Foo()
foo.foo(v: "") // prints foo<T>(v: T)
foo.foo(x: 1, v: "") // prints foo<T>(x: Int, v: T)
foo.foo(x: 1, v: "") // prints foo<T>(x: Int, v: T)
foo.foo(x: 1, v: "") // prints foo<T>(x: Int, v: T)