符合 Swift 协议的泛型类型

Posted

技术标签:

【中文标题】符合 Swift 协议的泛型类型【英文标题】:generic type conforming to a protocol in Swift 【发布时间】:2014-12-09 01:45:24 【问题描述】:

是否可以要求泛型类型的特定实例化符合 Swift 中的协议?

例如,假设我有一个名为Thing<T> 的泛型类型。我希望Thing<Int> 符合某个协议,而不是Thing<T>

【问题讨论】:

听起来像是你想要的某种巫术 Thing<T where if T : A then T : B>; Thing<T where T : B when T : A>; Thing<T where T : A ?? B> 那些行不通,但那是你想写的东西,对吗?我认为您现在可以得到的最接近的方法是检查可失败初始化程序中的一致性,并在一致性不符合您的要求时返回 nil。 您要的是ConstraintKinds,这是高级类型系统的一个特性。考虑到我们甚至没有常规类型,更不用说类型族了,真的没有办法解决这个问题。 我们没有自动协议一致性。如果你实现了所有的方法 你想对 Thing 的约束协议做什么? 【参考方案1】:

好吧,它可能不会太繁琐,而且很明显你已经忽略了它,但你可以做一个“泛型类型的特定实例化”——如:

class ThingOfInt : Thing<Int>, SpecialIntProtocol 
 // implement SpecialIntProtocol (if it isn't already 
 // implemented in an extension)

或者更笼统地说:

class IntThing<T:IntegerType> : MyThing<T>, SpecialIntProtocol 

【讨论】:

不幸的是,这不是一个通用的答案,因为我要约束的类型是enum,因此不能被子类化。如,“如果枚举类型为Int,则使其符合协议X 这是另一个不错且正确的答案......但另一个问题:-(【参考方案2】:

Swift 2.0 中,您可以扩展协议和类型

当你扩展它时,你可以添加一个通用的where 约束。只有符合该规则的类型才能使用该功能

示例

public struct Thing<T> 
  let x: T


extension Thing where T : IntegerType 
  func giveMeInt () -> T 
    return x
  


let a = Thing<Int>(x: 10)
a.giveMeInt()

let b = Thing(x: 10.1)
//b.giveMeInt() // Error

这样你可以为Thing&lt;Int&gt;类型添加额外的功能

我不知道在扩展中符合协议的方法,但这没有多大意义。

限制: Generic where T : 可以与协议和类一起使用,这就是为什么我们不能在那里指定 Int

【讨论】:

不幸的是,这并没有回答他的问题,因为他希望 Thing 符合与 T 相关的特定协议。 我知道,只是想证明这是可能的。另外我认为您应该观看面向协议的编程 WWDC15 会议。在特定泛型的扩展中添加协议构造确实有意义 不,你没有表明这是可能的。你只是表明了与问题无关的事情是可能的。问题是关于使泛型类型符合协议,而在您的回答中甚至没有协议,无处可去。这是一个很好的答案……但是对于一个完全不同的问题。 cfisher 可能知道通过扩展使对象符合协议,他想知道泛型如何做到这一点。【参考方案3】:

您可以使用where 关键字并在后面传递条件。在 Where 子句部分看到了这个 https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-XID_275

class Thing<T : SomeProtocol where reflect(T).summary != "Int"> 
    ...

【讨论】:

类型约束中的where 子句仅接受:== 条件,并在编译时进行评估。 (reflect(T).summary != "Int" 是运行时表达式)

以上是关于符合 Swift 协议的泛型类型的主要内容,如果未能解决你的问题,请参考以下文章

符合两种协议的Swift泛型类型

泛型类的基本使用

Swift 中的泛型数组

在 Typescript 的泛型类中初始化泛型类型

JAVA中的泛型类是啥东西?

只能采用某些类型的泛型类