无法将协议传递给具有约束泛型类型的函数

时间:2015-08-20 23:23:27

标签: swift generics protocols swift2

如果您的函数具有受协议限制的泛型类型,则无法将协议类型的值传递给函数:

protocol P {}

extension Int: P {}

func testP<T: P>(value: T) {}

// passing Int
let val = 0
testP(val)

// passing Int as P (protocol)
let valAsP: P = 0
testP(valAsP) // error: cannot invoke 'testP' with an argument list of type '(P)'

如果我将协议更改为类(并使用继承),则在两种情况下都会执行相同的函数。

此外,“Swift编程语言”一书中写道

  

声明中的冒号意味着“......类型......”,

如果对于通用约束也是如此,我认为这是一个错误。

那么这应该被视为一个错误吗?或者有这种行为有用吗?

1 个答案:

答案 0 :(得分:1)

是的,根据Types部分定义的规范:

  

命名类型是一种在定义时可以赋予特定名称的类型。命名类型包括类,结构,枚举和协议

协议是有效的命名类型。

还支持以下事实:如果您从P删除testP约束,则代码会进行编译。

您可以通过将testP的签名更改为

来解决您的问题
func testP(value: P) {}

适用于大多数情况。

顺便提一下,您的方案是possible in C#,其中接口类似于Swift中的协议

我创建了问题SR-1324