首页 文章

带有重载泛型方法的重载解决问题

提问于
浏览
1

我确实遇到了重载泛型方法的问题 . 考虑这个例子:

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

这让我相信这是编译器中的一个问题 . 我提交了一份错误报告 .

2 回答

  • 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)
    
  • 1

    尝试在第一个参数之前删除“x:”,如:

    foo.foo(1, v: "")
    

    UPDATED

    对于 methods ,默认行为是:

    具体来说,默认情况下,Swift在方法中为第一个参数名称提供本地参数名称,默认情况下为第二个和后续参数名称提供本地和外部参数名称 .

    对于 functions

    如果希望函数用户在调用函数时提供参数名称,请为本地参数名称定义每个参数的外部参数名称 . 您在它支持的本地参数名称之前编写外部参数名称,用空格分隔:...

    文件还在功能中说:

    如果为参数提供外部参数名称,则在调用该函数时必须始终使用该外部名称 .

    看起来这对于方法来说是正确的,这就是 foo.foo(1, v: "") 仅适用于方法的原因,因为有一个外部参数名称,你必须使用它 .

相关问题