【问题标题】:Generic override in swift extension not being calledswift扩展中的通用覆盖没有被调用
【发布时间】:2019-05-14 18:42:32
【问题描述】:

我有一个泛型类型

enum ResultState<T> {
    case found(T)
}

有一些扩展

extension ResultState {

    func hello() { print("Hello") }
}

extension ResultState where T: Collection {

    func hello() { print("Hello, collection") }
}

这些工作完美无缺,完全符合我的预期:

ResultState.found(1).hello() // prints "Hello"
ResultState.found([1]).hello() // prints "Hello, collection"

但是,如果它们是从另一个泛型函数中调用的,它的行为就不一样了

func myFunction<T>(_ state: ResultState<T>) {
    state.hello()
}

例如,

myFunction(ResultState.found(1)) // prints "Hello"
myFunction(ResultState.found([1]) // prints "Hello"

现在,每次都会调用基本版本的 hello,尽管检查 myFunction 中的 T 显示它肯定是 Array&lt;Int&gt;

这是预期的 Swift 行为吗?

如果是这样,我将如何解决它 - 如何从 myFunction 中调用正确版本的 hello

【问题讨论】:

  • 奇怪!!!

标签: swift generics overriding


【解决方案1】:

在我看来,myFunction 的信息丢失了,并且只应用了一个级别,可以说是 ResultState。不确定这是您想要的解决方案,但一种方法是以相同的方式定义不同的函数,就像您有不同的扩展一样。

func myFunction<T: Collection>(_ state: ResultState<T>)  {
    state.hello()
}

func myFunction<T>(_ state: ResultState<T>)  {
    state.hello()
}

执行

ResultState.found(1).hello() 
ResultState.found([1]).hello() 

myFunction(ResultState.found(1))
myFunction(ResultState.found([1]))

将产生

你好
你好,收藏
你好
你好,收藏

【讨论】:

  • 是的,烦人的是,这也是我唯一能想到的 :( 我试图在 myFunction 级别没有多个函数,以防我需要为其他类型的 T 扩展 ResultState -理想情况下,我应该能够做到这一点而无需触及任何其他代码。不过感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 2015-10-04
  • 2013-07-09
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多