【问题标题】:Swift Generic constraints in initinit 中的 Swift 通用约束
【发布时间】:2015-07-29 14:44:05
【问题描述】:

我有通用的,我希望能够使用特定的约束对其进行初始化。约束仅用于初始化。班上的其他人不在乎。这是一个简化的例子:

struct Generic<T> {
  let compare: (T, T) -> Bool
  init<T: Equatable>(data: [T]) {
    let handler: (T, T) -> Bool = { $0 == $1 }
    compare = handler
    insert(data)
  }

  init(compareHandler: (T, T) -> Bool, data[T]) {
    compare = self.compareHandler
    insert(data)
  }
}

您可以看到有两个初始化程序。第二个显然工作正常。但是,在第一个中,本地类型 T 与结构的泛型类型不匹配。因此,例如,尝试插入数据我得到Cannot invoke 'insert' with an argument list of type '([T])'。我是否可以将 Struct 的泛型类型专门用于初始化或特定功能?

注意,我已经尝试init&lt;T where T:Equatable&gt;(data: [T]) 达到同样的效果。

更新

我正在使用以下解决方法:我创建了一个顶级函数并删除了专门的 init:

func equatableHandler<T: Equatable>(left: T, right: T) -> Bool {
  return left == right
}

结构的客户端可以使用:Generic(compareHandler: equatableHandler, data: data)进行初始化

使用专门的init 并不是很“方便”,但我认为它对我的目的来说已经足够好了。我不喜欢创建顶级函数,但泛型经常用于“Equatable”泛型,因此我定义一次处理程序供客户使用是有意义的。

【问题讨论】:

  • 我现在无法测试,但这可以工作:init&lt;P: Equatable where T == P&gt;(data: [P])
  • 这是一个不错的想法,但它也不起作用。尽管有T == P 条件,编译器仍然认为它们在init 函数中不相等。

标签: swift generics init


【解决方案1】:

问题是第一个init方法

init<T: Equatable>(data: [T]) 

引入了一个本地类型占位符T,它隐藏(并且完全 无关)占位符TGeneric 类型,所以它 本质上和Array extension to remove object by value中的问题是一样的。

从 Swift 2 开始,您可以使用“受限扩展”来解决这个问题:

extension Generic where T : Equatable {
    init(data: [T]) {
        let handler: (T, T) -> Bool = { $0 == $1 }
        compare = handler
        // ...
    }
}

对于 Swift 1.x,唯一的解决方案可能是定义一个全局帮助器 功能

func makeGeneric<T : Equatable>(data: [T]) -> Generic<T> {
    return Generic(compareHandler:  { $0 == $1 }, data: data)
}

(我想不出一个合理的函数名称:)。

【讨论】:

  • 这是对 Swift 2 中扩展功能的一次绝妙使用!
  • 不幸的是,这是生产代码,所以我还不能使用 Swift 2。虽然这看起来可以在 Swift 2 中使用,但我目前无法验证它。
  • 是的,确实有效。它类似于我的解决方法,只是您创建了一个工厂方法,而我只是提供了一个便利处理程序。奇怪的是,我确实尝试在 Struct 中使用static func 执行此操作,但最终还是出现了类型不匹配。我会将您的答案标记为已接受,因为我认为除了等到 Swift 2 到来之外,没有真正的方法可以做我想做的事。 :)
猜你喜欢
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 2017-03-04
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多