【问题标题】:Swift Generic func gen<T>(arg: T) where T : Optional<U>, U : EquatableSwift Generic func gen<T>(arg: T) where T : Optional<U>, U : Equatable
【发布时间】:2017-02-07 00:48:17
【问题描述】:

如何表达一个 Swift 泛型函数,它限制 TOptional&lt;Equatable&gt;

我已经尝试了以下类似的方法,但出现了错误。

func gen&lt;T&gt;(arg: T) where T : Optional&lt;Equatable&gt;

  • 类型“T”被限制为非协议类型“可选”

func gen&lt;T&gt;(arg: T) where T : OptionalProtocol&lt;Equatable&gt;

  • 无法专门化非泛型类型“OptionalProtocol”

func gen&lt;T, U&gt;(arg: T) where T : Optional&lt;U&gt;, U : Equatable

  • 类型“T”被限制为非协议类型“可选”
  • 函数签名中未使用通用参数“U”

谢谢。

编辑

我正在做类似的事情

if let a = arg, let b = argb
    return a==b

事实证明,我的错误根本不在模板中,只是我正在使用的对象实际上不是 Equatable。我想我假设 Swift 会为一个结构体生成 ==,它的元素本身都是 =='able,但事实并非如此。下次我会知道错误Expression type 'Bool' is ambiguous without more context 是什么意思。

【问题讨论】:

  • 如果我遗漏了一些东西,我很抱歉,但你可以使用 'arg: T 吗?在你的第一个例子中?

标签: swift generics


【解决方案1】:

这应该可行:

func gen<T>(arg: T?) where T : Equatable { /*...*/ }

相当于这个:

func gen<T>(arg: Optional<T>) where T : Equatable { /*...*/ }

记住,

  1. 泛型适用于类型要求的可变部分。您需要Optional 是不变的;这是可变的可选-what 部分。所以将可选性放在实际的 func 声明中,而将可选-what 留给泛型。

  2. 类型参数中的冒号表示子类型关系。类型T 不能是Optional&lt;Something&gt; 的子类型,因为Optional 是一个枚举——只有类和协议可以有子类型(分别是子类和符合类型)。同样,泛型不是协变的,所以Optional&lt;Foo&gt; 中的Foo 采用Equatable 不是Optional&lt;T: Equatable&gt; 的子类型。

【讨论】:

    【解决方案2】:
    func gen<T>(arg: T?) where T : Equatable {
    
        if let arg = arg {
            print("arg is '\(arg)', Equatable")
        } else {
            print("arg is nil")
        }
    }
    

    使用示例

    let testValue1: Int? = 1
    gen(arg: testValue1)
    
    let testValue2: String? = "One"
    gen(arg: testValue2)
    
    let testValue3: String? = nil
    gen(arg: testValue3)
    

    控制台输出

    arg is '1', Equatable
    
    arg is 'One', Equatable
    
    arg is nil
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多