init中的Swift通用约束

时间:2015-07-29 14:44:06

标签: swift generics init

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

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<T where T:Equatable>(data: [T])同样的效果了。

更新

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

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

结构体的客户端可以使用:Generic(compareHandler: equatableHandler, data: data)

进行初始化

这不是使用专门的init的“便利”,但我认为它对我的目的来说足够好。我不是创建顶级函数的粉丝,但泛型经常用于“Equatable”泛型,因此我有必要为客户端定义一次处理程序。

1 个答案:

答案 0 :(得分:5)

问题是第一个init方法

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

引入了隐藏(并且完全是)的本地类型占位符TT类型的占位符Generic无关,所以它 与Array extension to remove object by value中的问题基本相同。

从Swift 2开始,你可以使用&#34;限制扩展来解决这个问题&#34;:

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)
}

(我想不出这个功能的合理名称:)。