init中的Swift通用约束 [英] Swift Generic constraints in init

查看:116
本文介绍了init中的Swift通用约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有通用的,我想能够用特定的约束来初始化它。约束仅用于初始化。其他同学不在乎。这是一个简化的例子:

  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 与结构的泛型类型不匹配。因此,例如,尝试插入数据,我得到不能用'([T])'类型的参数列表调用'insert'。我是否可以将Struct的泛型类型专门化为初始化或特定函数?注意,我已经试过 init< T,其中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< p> T:Equatable>(数据:[T])

引入了一个局部类型占位符 ,它隐藏了 Generic T (完全与
无关) c $ c> type,所以它
基本上与数组扩展,以便按值删除对象



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

 扩展名泛型where T:可等值{
init(data:[T]){
let handler:(T,T) - > Bool = {$ 0 == $ 1}
compare = handler
// ...
}
}

对于Swift 1.x唯一的解决方案可能是定义一个全局助手
函数

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

(并且我想不出这个函数的明智名称)。


I have generic and I want to be able to initialize it with specific constrains. The constraints are only there for initialization. The rest of the class doesn't care. Here is a simplified example:

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

You can see there's two initializers. The second one obviously works fine. However, in the first one the local type T is mismatched with the struct's generic Type. So, for example, attempting to insert data I get Cannot invoke 'insert' with an argument list of type '([T])'. Is it possible for me to specialize the Struct's generic type only for the initialization or a specific function?

Note, I've already tried init<T where T:Equatable>(data: [T]) to the same effect.

Update

I'm using the following workaround: I create a top level function and removing the specialized init:

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

Clients of the struct can initialize using: Generic(compareHandler: equatableHandler, data: data)

It's not quite the "convenience" of using a specialized init, but I suppose it works well enough for my purposes. I'm not a fan of creating top-level functions, but the generic is used so often for "Equatable" generics that it makes sense for me to define the handler once for clients to use.

解决方案

The problem is that the first init method

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

introduces a local type placeholder T which hides (and is completely unrelated to) the placeholder T of the Generic type, so it is essentially the same problem as in Array extension to remove object by value.

As of Swift 2 you can solve that with a "restricted extension":

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

For Swift 1.x the only solution is probably to define a global helper function

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

(and I could not think of a sensible name for the function :).

这篇关于init中的Swift通用约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆