Swift中的多个types约束
比方说,我有这些协议:
protocol SomeProtocol { } protocol SomeOtherProtocol { }  现在,如果我想要一个采用genericstypes的函数,但该types必须符合SomeProtocol我可以这样做: 
 func someFunc<T: SomeProtocol>(arg: T) { // do stuff } 
但有没有办法为多个协议添加types约束?
 func bothFunc<T: SomeProtocol | SomeOtherProtocol>(arg: T) { } 
类似的东西使用逗号,但在这种情况下,它将开始另一种types的声明。 这是我试过的。
 <T: SomeProtocol | SomeOtherProtocol> <T: SomeProtocol , SomeOtherProtocol> <T: SomeProtocol : SomeOtherProtocol> 
	
您可以使用where子句 ,它允许您指定任意数量的需求(所有必须满足的需求),并以逗号分隔
Swift 2:
 func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) { // stuff } 
Swift 3:
 func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) { // stuff } 
或者更强大的where子句:
 func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{ // stuff } 
 您当然可以使用协议组合(例如, protocol<SomeProtocol, SomeOtherProtocol> ),但它有点不灵活。 
 使用where让你处理涉及多种types的情况。 
您可能仍然想要在多个地方编写协议以便重复使用,或者只是为了使协议成为有意义的名称。
你有两种可能性:
- 
您使用Jiaaro的答案中指出的where子句 : func someFunc<T where T : SomeProtocol, T : SomeOtherProtocol>(arg: T) { // do stuff }
- 
您使用协议组合types : func someFunc<T : protocol<SomeProtocol, SomeOtherProtocol>>(arg: T) { // do stuff }
Swift 3.0的演变带来了一些变化。 现在我们的两个select看起来有些不同。
  在Swift 3.0中使用where子句: 
 现在where子句已经移到了函数签名的末尾,以提高可读性。 所以多协议inheritance现在看起来像这样: 
 func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol { } 
  在Swift 3.0中使用protocol<>构造: 
 使用protocol<>构造的组合被弃用。 较早的protocol<SomeProtocol, SomeOtherProtocol>现在看起来像这样: 
 func someFunc<T:SomeProtocol & SomeOtherProtocol>(arg: T) { } 
引用。
 更多信息在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
Swift 3提供了多达3种不同的方式来声明你的function。
 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) { /* ... */ }