扩展和直接调用协议的区别
Difference between extension and direct call for protocol
我得到了这个代码:
protocol Protocol {
var id: Int { get }
}
extension Array where Element: Protocol {
func contains(_protocol: Protocol) -> Bool {
return contains(where: { [=10=].id == _protocol.id })
}
}
class Class {
func method<T: Protocol>(_protocol: T) {
var arr = [Protocol]()
// Does compile
let contains = arr.contains(where: { [=10=].id == _protocol.id })
// Doens't compile
arr.contains(_protocol: _protocol)
}
}
为什么我评论“无法编译”的代码行无法编译?这是错误:
Incorrect argument label in call (have '_protocol:', expected 'where:')
当我将扩展中的方法名称更改为其他名称时,例如 containz
(当然还将调用它的方法的名称更改为 containz
),当我尝试调用它:
Using 'Protocol' as a concrete type conforming to protocol 'Protocol' is not supported
但为什么我尝试通过扩展程序调用它时它不起作用,但是当我直接在扩展程序中创建函数时它却起作用?我看不出有什么区别。
我同意 matt 的基本答案是 ,但无论如何它可能都值得回答,因为在这种情况下答案非常简单。首先,阅读关于为什么 [Protocol]
不像你想象的那样工作的链接问题(尤其是 Hamish 的回答,它比我写的公认答案更广泛)。 [Protocol]
不匹配 where Element: Protocol
子句,因为 Protocol
不是符合 Protocol
的具体类型(因为它不是具体类型)。
但这里不需要 [Protocol]
。你有 T: Protocol
,所以你可以(并且应该)只使用它:
var arr = [T]()
有了这个改变,其余的应该会像你预期的那样工作,因为 T
是一个符合协议的具体类型。
我得到了这个代码:
protocol Protocol {
var id: Int { get }
}
extension Array where Element: Protocol {
func contains(_protocol: Protocol) -> Bool {
return contains(where: { [=10=].id == _protocol.id })
}
}
class Class {
func method<T: Protocol>(_protocol: T) {
var arr = [Protocol]()
// Does compile
let contains = arr.contains(where: { [=10=].id == _protocol.id })
// Doens't compile
arr.contains(_protocol: _protocol)
}
}
为什么我评论“无法编译”的代码行无法编译?这是错误:
Incorrect argument label in call (have '_protocol:', expected 'where:')
当我将扩展中的方法名称更改为其他名称时,例如 containz
(当然还将调用它的方法的名称更改为 containz
),当我尝试调用它:
Using 'Protocol' as a concrete type conforming to protocol 'Protocol' is not supported
但为什么我尝试通过扩展程序调用它时它不起作用,但是当我直接在扩展程序中创建函数时它却起作用?我看不出有什么区别。
我同意 matt 的基本答案是 [Protocol]
不像你想象的那样工作的链接问题(尤其是 Hamish 的回答,它比我写的公认答案更广泛)。 [Protocol]
不匹配 where Element: Protocol
子句,因为 Protocol
不是符合 Protocol
的具体类型(因为它不是具体类型)。
但这里不需要 [Protocol]
。你有 T: Protocol
,所以你可以(并且应该)只使用它:
var arr = [T]()
有了这个改变,其余的应该会像你预期的那样工作,因为 T
是一个符合协议的具体类型。