繁体   English   中英

init中的Swift通用约束

[英]Swift Generic constraints in 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
}

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

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

问题是第一个init方法

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

引入了一个本地类型的占位符T ,它隐藏(并且完全不相关) Generic类型的占位符T ,因此它与Array扩展中的问题基本上是相同的问题。

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

(我无法想到这个功能的合理名称:)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM