【问题标题】:What's the difference between using or not using the 'where' clause with generics?使用或不使用泛型的“where”子句有什么区别?
【发布时间】:2017-10-18 12:18:08
【问题描述】:

这两种声明泛型超类的方法有或没有'where'子句有什么区别?

func foo<T: SomeClass>(object: T) -> Array<T>

func foo<T>(object: T) -> Array<T> where T: SomeClass

【问题讨论】:

    标签: swift generics


    【解决方案1】:

    这在Swift guide中有明确说明:

    通用 where 子句中的要求指定一个类型 参数继承自类或符合协议或协议 作品。虽然通用的 where 子句提供了句法 用于表达对类型参数的简单约束的糖(对于 例如,&lt;T: Comparable&gt; 等价于 &lt;T&gt; where T: Comparable 和 等等),您可以使用它来提供更复杂的类型约束 参数及其相关类型。例如,您可以约束 类型参数的关联类型以符合协议。为了 例如,&lt;S: Sequence&gt; where S.Iterator.Element: Equatable 指定 S 符合 Sequence 协议并且关联的类型 S.Iterator.Element 符合 Equatable 协议。这个约束 确保序列的每个元素都是等价的。

    简单地说,where 允许您指定有关泛型参数的关联类型的约束,而在 &lt;&gt; 中您不能这样做。

    【讨论】:

      【解决方案2】:

      像这样的问题总是需要一些实际的例子,即使是最简单的例子来获得基本的想法。否则,它通常仍然是理论上的。

      正如 Sweeper 所引用的,where 之后的内容称为类型约束。通常,您指定一个或多个协议,这些协议引入了传递的对象或类型必须满足的条件。如前所述,只有在where 之后,您才能指定泛型类型的associatedtype 约束。

      考虑以下示例:

      protocol MyProtocol {
          associatedtype AType
      
          func foo()
      }
      
      class MyClassInt : NSObject, MyProtocol {
          typealias AType = Int
      
          func foo() {
              print(type(of: self))
          }
      }
      
      class MyClassString : NSObject, MyProtocol {
          typealias AType = String
      
          func foo() {
              print("I'm not implemented")
          }
      }
      
      extension MyProtocol where Self.AType == Int {
          func test() {
              self.foo()
          }
      }
      

      现在检查我们的东西:

      let str = MyClassString()
      str.test() // Won't compile !! 
      

      'MyClassString.AType'(又名'String')不能转换为'Int'

      这个编译运行:

      let int = MyClassInt()
      int.test()
      

      在这个例子中,我们有一个指定了associatedtype 的协议。还有一个extension,它只适用于我们的MyProtocol,特别是associatedtype,在我们的例子中是Int。该扩展定义了单一方法。如您所见,编译器不允许我们使用associatedtype 调用该方法,而不是由约束指定的方法,即使MyClassString 也实现了该协议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-24
        • 2010-12-01
        • 1970-01-01
        • 2015-05-30
        • 1970-01-01
        • 2018-02-23
        • 2012-01-08
        • 1970-01-01
        相关资源
        最近更新 更多