为什么Swift不能通过扩展泛型where子句调用函数?

时间:2019-04-23 09:45:43

标签: swift xcode generics

如果我从具有扩展where子句的类的类中调用函数(例如funcB),则所有子句都按预期工作。

但是如果我调用一个类的另一个函数(例如funcA)并在内部使用funcB调用函数,我会看到原始funcB而不是扩展的结果。

代码示例:

class Bar {

}

class Foo<T> {

    func funcA() {
        funcB()
    }

    func funcB() {
        print("Parent without clause")
    }

}

extension Foo where T: Bar {

    func funcB() {
        print("Parent + clause")
    }

}

Foo<Any>().funcB()

Foo<Bar>().funcB()

print("--")

Foo<Any>().funcA()

Foo<Bar>().funcA()

输出:

  

没有条款的父母

     

父母+条款

     

-

     

没有条款的父母

     

没有条款的父母

我想根据T的父级调用不同的实现,并将T发送给第二个类。

如果T是Bar的子代,请使用Class ,否则返回nil。

2 个答案:

答案 0 :(得分:2)

要具有某种“抽象”类行为,可以使用协议而不是通用类。

类似这样的东西:

class Bar: FooProtocol {
}

class Foo: FooProtocol {
}

protocol FooProtocol {
    func funcA()
    func funcB()
}

extension FooProtocol {
    func funcA() {
        funcB()
    }

    func funcB() {
        print("Parent without clause")
    }
}

extension FooProtocol where Self: Bar {
    func funcB() {
        print("Parent + clause")
    }
}

这里我为FooProtocol使用了默认实现,但是您可以根据需要定义Foo类和Bar类的函数。 然后,您将得到以下结果:

    let bar = Bar()
    bar.funcA() // Parent + clause
    bar.funcB() // Parent + clause

    let foo = Foo()
    foo.funcA() // Parent without clause
    foo.funcB() // Parent without clause

答案 1 :(得分:0)

这是当前Swift实现的正确行为。

https://bugs.swift.org/browse/SR-10549