Swift 尝试在闭包中使用泛型类型时出现意外编译器错误
给出一个没有任何恐惧的协议:Swift 尝试在闭包中使用泛型类型时出现意外编译器错误,swift,generics,Swift,Generics,给出一个没有任何恐惧的协议: protocol NonFunkyProtocol {} 还有一个带有严重恐惧的协议: protocol FunkyProtocol { func funky<T: NonFunkyProtocol>(_ closure: (T) -> Void) } 协议funky协议{ func funky(u闭包:(T)->Void) } 然后给出这个结构: struct WeeStruct: FunkyProtocol { let w
protocol NonFunkyProtocol {}
还有一个带有严重恐惧的协议:
protocol FunkyProtocol {
func funky<T: NonFunkyProtocol>(_ closure: (T) -> Void)
}
协议funky协议{
func funky(u闭包:(T)->Void)
}
然后给出这个结构:
struct WeeStruct: FunkyProtocol {
let weeProp: NonFunkyProtocol
func funky<T>(_ closure: (T) -> Void) where T: NonFunkyProtocol {
closure(weeProp)
}
}
struct-weeststruct:FunkyProtocol{
让我们哭泣吧:非未知的协议
func funky(u-闭包:(T)->Void)其中T:NonFunkyProtocol{
关闭(排水管)
}
}
我希望将其编译为closure
中预期的参数类型为T,其中T符合非unknyprotocol,而weeProp
为非unknyprotocol类型
相反,我看到了这个错误:
我很可能在我的泛型知识中有一个漏洞,我错在哪里了?问题是
T
在这种情况下是“符合非未知协议的某种类型”weeProp
也是“符合NonFunkyProtocol
”的东西,但是没有任何东西表明weeProp
属于T
类型
考虑以下情况:
extension Int: NonFunkyProtocol {}
extension String: NonFunkyProtocol {}
Int和String都符合
现在我用一个字符串构造一个WeeStruct:
let wee = WeeStruct(weeProp: "")
我用一个需要Int的函数调用funky
(因为Int是一致类型,它可以是T
):
因此,这将传递给闭包。这怎么行
因此,您需要要求闭包句柄anyNonFunkyProtocol
(我强烈怀疑这就是您的意思):
或者您需要通过使T
成为关联类型,将weeProp
固定到T
:
protocol FunkyProtocol {
associatedtype T: NonFunkyProtocol
func funky(_ closure: (T) -> Void)
}
struct WeeStruct<T:NonFunkyProtocol>: FunkyProtocol {
let weeProp: T
func funky(_ closure: (T) -> Void) {
closure(weeProp)
}
}
协议funky协议{
关联类型T:非未知协议
func funky(u-闭包:(T)->Void)
}
结构WeeStruct:FunkyProtocol{
让我们哭泣吧
func funky(u-闭包:(T)->Void){
关闭(排水管)
}
}
不过,在添加关联类型之前,我会非常小心。这完全改变了FunkyProtocol的本质
如果FunkyProtocol真的只是这一个需求,那么您还应该询问它解决了什么,而不仅仅是一个函数。当您可以直接使用wee.funky
功能时,为什么要传递weestuct
及其所有协议行李?FunkyProtocol上有协议扩展吗?如果您不能编写针对FunkyProtocol的通用算法,那么它可能不应该是一个协议。Lightbull矩!非常感谢,在这个特殊的例子中,你是对的,它不应该是一个协议,但它只是一个非常精炼的例子,试图围绕我在一个项目中遇到的问题来思考。
func funky(_ closure: (NonFunkyProtocol) -> Void)
protocol FunkyProtocol {
associatedtype T: NonFunkyProtocol
func funky(_ closure: (T) -> Void)
}
struct WeeStruct<T:NonFunkyProtocol>: FunkyProtocol {
let weeProp: T
func funky(_ closure: (T) -> Void) {
closure(weeProp)
}
}