首页 文章

Swift中的多类型约束

提问于
浏览
105

假设我有这些协议:

protocol SomeProtocol {

}

protocol SomeOtherProtocol {

}

现在,如果我想要一个采用泛型类型的函数,但该类型必须符合 SomeProtocol 我可以这样做:

func someFunc<T: SomeProtocol>(arg: T) {
    // do stuff
}

但有没有办法为多个协议添加类型约束?

func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) {

}

类似的东西使用逗号,但在这种情况下,它会启动一个不同类型的声明 . 这是我尝试过的 .

<T: SomeProtocol | SomeOtherProtocol>
<T: SomeProtocol , SomeOtherProtocol>
<T: SomeProtocol : SomeOtherProtocol>

4 回答

  • 15

    您可以使用where clause,它允许您指定任意数量的要求(所有必须满足的要求)以逗号分隔

    斯威夫特2:

    func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) {
        // stuff
    }
    

    Swift 3&4:

    func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
        // stuff
    }
    

    或更强大的where子句:

    func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{
        // stuff
    }
    

    您当然可以使用协议组合(例如, protocol<SomeProtocol, SomeOtherProtocol> ),但它的灵活性稍差 .

    使用 where 可以处理涉及多种类型的情况 .

    您可能仍希望在多个位置组合协议以便重用,或者只是为组合协议提供有意义的名称 .

  • 11

    你有两种可能性:

    • 如Jiaaro的答案所示,您使用 where clause
    func someFunc<T where T : SomeProtocol, T : SomeOtherProtocol>(arg: T) {
        // do stuff
    }
    
    • 您使用 protocol composition type
    func someFunc<T : protocol<SomeProtocol, SomeOtherProtocol>>(arg: T) {
        // do stuff
    }
    
  • 72

    Swift 3.0的发展带来了一些变化 . 我们的两个选择现在看起来有点不同 .

    Using a where clause in Swift 3.0:

    where 子句现在已移至函数签名的末尾以提高可读性 . 所以多协议继承现在看起来像这样:

    func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol {
    
    }
    

    Using the protocol<> construct in Swift 3.0:

    使用 protocol<> 构造的合成已被弃用 . 早期的 protocol<SomeProtocol, SomeOtherProtocol> 现在看起来像这样:

    func someFunc<T:SomeProtocol & SomeOtherProtocol>(arg: T) {
    
    }
    

    References.

    有关 where 更改的更多信息,请访问:https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md

    而且,有关协议<>构造的更改的更多内容如下:https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md

  • 202

    Swift 3提供多达3种不同的方式来声明您的功能 .

    protocol SomeProtocol {
        /* ... */
    }
    
    protocol SomeOtherProtocol {
        /* ... */        
    }
    

    1.使用&运算符

    func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
        /* ... */
    }
    

    2.使用where子句

    func someFunc<T>(arg: T) where T: SomeProtocol, T: SomeOtherProtocol {
        /* ... */
    }
    

    3.使用where子句和&运算符

    func someFunc<T>(arg: T) where T: SomeProtocol & SomeOtherProtocol {
        /* ... */        
    }
    

    另请注意,您可以使用 typealias 来缩短功能声明 .

    typealias RequiredProtocols = SomeProtocol & SomeOtherProtocol
    
    func someFunc<T: RequiredProtocols>(arg: T) {
        /* ... */   
    }
    

相关问题