我正在做一些框架,遇到了一个问题。
我有一个公共协议:
public protocol MyPublicProtocol1 {
}
和另一个,它包含一个传递了泛型参数的函数。泛型参数具有约束-参数类型必须实现第一个公共协议:
public protocol MyPublicProtocol2 {
func someFunc<T: MyPublicProtocol1>(completion: (T) -> ())
}
那么我就不在公共课上实现我的协议。在那个带泛型参数的函数中,我必须调用另一个不带泛型参数的函数,看起来像这样:
func anotherFuncWith(completion: (MyPublicProtocol1) -> ())
下面是实现的样子:
class MyPublicProtocol1Impl: MyPublicProtocol1 {
}
class MyPublicProtocol2Impl: MyPublicProtocol2 {
func someFunc<T: MyPublicProtocol1>(completion: (T) -> ()) {
anotherFuncWith(completion: completion)
}
}
当然最后一个字符串有个错误。
我不能声明 someFunc(completion:),而不是像这样的泛型参数:
func someFunc(completion: (MyPublicProtocol1Impl) -> ())
因为 * MyPublicProtocol 1 Impl * 类不能是公共的。由于某些原因,我也不能声明anotherFuncWith(completion:)
接受泛型参数。
有没有一种方法可以将(T: MyPublicProtocol1) -> ()
完成转换为(MyPublicProtocol1) -> ()
?
任何帮助或建议都非常感谢!谢谢你阅读我的故事!
2条答案
按热度按时间ercv8c1e1#
你要求的是无法证明的事实。你有一个方法:
它接受一个可以接收 * any *
MyPublicProtocol1
的方法。然后你传递给它一个类型的方法:anotherFuncWith
可能传递不是T
的内容,此时这是未定义的。为了更具体,让我们去掉这里的大部分内容,使MyPublicProtocol1
成为Any
(只是选择一个普通的协议)。这无法完全像您的示例那样编译。现在让我们想想,如果它 * 确实 * 编译了,我可以做什么。我可以打电话:
所以现在
anotherFuncWith
调用complete
,传递一个不能添加的String
。撞车这里的根本问题是您已经得到了covariance and contravariance。
我们怎么解决那要看你的意思了这个代码有点奇怪。你关心
T
的实际类型吗?你好像从来没用过。如果你不在乎,那就使用协议:如果你关心实际的类型,使用PAT:
或者你可能想重新考虑一下是否需要一个协议。我经常发现人们在还不需要的时候就去找协议。您是否有这些协议的多种实现?是否有多个类型被传递?如果没有,我会简化,只有当你有一个真正的问题,你正在解决当前的代码时,才使用泛型/协议。(你可能需要它们;这只是我的股票建议,许多人发现当他们过度设计时很有用。
jc3wubiy2#
绕过这件事的卑鄙方法是
我只会这样做,如果你是 * 非常 * 肯定的代码围绕它,因为它肯定是易错的。
还有,这个也行。我不确定你实际上想做什么,所以我不确定它是否能解决你的问题