加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 如何调用更具体的重载方法

发布时间:2020-12-14 04:57:48 所属栏目:百科 来源:网络整理
导读:这是一个示例游乐场: protocol P { associatedtype T func getValue() - T}class Foo: P { func getValue() - String { return "hello" }}class Bar { func testT: P(_ o: T) { print("Generic",o.getValue()) } func test(_ o: Any) { print("Any") }}let
这是一个示例游乐场:

protocol P {
    associatedtype T
    func getValue() -> T
}

class Foo: P {
    func getValue() -> String {
        return "hello"
    }
}

class Bar {
    func test<T: P>(_ o: T) {
        print("Generic",o.getValue())
    }

    func test(_ o: Any) {
        print("Any")
    }
}

let foo = Foo()
let bar = Bar()
bar.test(foo)

这输出:任何.

如果我删除任何版本的测试,则调用泛型方法.
Foo类符合协议P,为什么Swift不选择泛型方法,因为它更具体?有没有办法调用通用的?

解决方法

据我所知,编译器在执行重载解析时总是倾向于使用显式类型参数而不是通用类型参数.因此,在测试< T:P>(_ o:T)和test(_ o:Any)之间的分辨率中 – 后者将是首选的,因为它具有显式(尽管是抽象的)参数类型,而第一个仅仅是占位符.

因此,如果您使第二个重载也是通用的,编译器现在将支持第一个重载,因为它们都没有显式类型化参数,但第一个重载受到更严格的限制:

class Bar {
    func test<T: P>(_ o: T) {
        print("Generic",o.getValue())
    }

    func test<T>(_ o: T) {
        print("Any")
    }
}

let foo = Foo()
let bar = Bar()
bar.test(foo) // Generic hello

保持过载原样,为了消除歧义,类型转换似乎也是一个可行的解决方案:

class Bar {
    func test<T: P>(_ o: T) {
        print("Generic",o.getValue())
    }

    func test(_ o: Any) {
        print("Any")
    }
}

let foo = Foo()
let bar = Bar()
(bar.test as (Foo) -> Void)(foo) // Generic hello

虽然我强烈建议使用第一种方法,因为它允许您更好地推断将选择什么样的过载(一般情况下,泛型也应该优先于协议类型的参数,due to the performance benefits of specialisation).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读