假设我有这些协议:

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>

推荐答案

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

Swift 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可以处理涉及多种类型的情况.

您可能仍然希望编写协议,以便在多个位置重用,或者只是给编写的协议起一个有意义的名称.

Swift 5:

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

这感觉更自然,因为协议就在争论的旁边.

Swift相关问答推荐

Form中的Divider在macOS上并不完全扩展

在visionOS 1.0中已弃用';base Color';:请改用`Color`属性

Swift 运算符中 inout 的行为

为什么变量不存储在 Swift 的过程数据区中

允许为 self 分配新的 struct 值的理由是什么?

将 ArgumentParser 与 Swift 并发一起使用

为什么在Swift中每次调用Decimal类型的formatted()方法都会越来越慢?

如何在类中打印函数

UUID 哈希值是不确定的吗?

如何在 SwiftUI 中用图像替换占位符文本?

这是 Int64 Swift Decoding 多余的吗?

try 制作一个 Swift 扩展来替换字符串中的多次出现

Swift 非参与者隔离闭包

Swift 有没有办法在不使用 switch 语句的情况下获取关联值?

如何处理永远不会失败的 String.Encoding 初始化程序?

AVPlayer 在 iOS 15.4 中寻求 completionHandler 返回 false

Xcode 7.3 Swift 的语法高亮和代码完成问题

如何实现 Swift 的 Comparable 协议?

将强制向下转换视为可选将永远不会产生零

iOS:如何检测用户是否订阅了自动更新订阅