如果您的函数具有受协议限制的泛型类型,则无法将协议类型的值传递给函数:
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编程语言”一书中写道
声明中的冒号意味着“......类型......”,
如果对于通用约束也是如此,我认为这是一个错误。
那么这应该被视为一个错误吗?或者有这种行为有用吗?
答案 0 :(得分:1)
是的,根据Types部分定义的规范:
命名类型是一种在定义时可以赋予特定名称的类型。命名类型包括类,结构,枚举和协议。
协议是有效的命名类型。
还支持以下事实:如果您从P
删除testP
约束,则代码会进行编译。
您可以通过将testP的签名更改为
来解决您的问题func testP(value: P) {}
适用于大多数情况。
顺便提一下,您的方案是possible in C#,其中接口类似于Swift中的协议
我创建了问题SR-1324