我正在研究一个框架,但遇到了一个问题。
我有一个公共协议:

public protocol MyPublicProtocol1 {
}

另一个,wich包含一个传递了泛型参数的函数。泛型参数具有约束-参数类型必须实现第一个公共协议:
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) -> ())

因为MyPublicProtocol1Impl类不能是公共的。出于某些原因,我也不能声明anotherFuncWith(completion:)来接受泛型参数。
有什么方法可以稍微“转换”(T:MyPublicProtocol1)->()完成为(MyPublicProtocol1)->()吗?
非常感谢您的帮助和建议!谢谢你读我的故事!

最佳答案

你要求的是不可证明的事实。你有一个方法:

func anotherFuncWith(completion: (MyPublicProtocol1) -> ())

它接受一个可以接收任何MyPublicProtocol1的方法。然后将类型为的方法传递给它:
(T: MyPublicProtocol1) -> ()

anotherFuncWith可能会传递一些未定义的内容。为了使它更具体,让我们去掉这里的大部分内容,并使T成为MyPublicProtocol1(只是选择一个简单的协议)。
func anotherFuncWith(completion: (Any) -> ()) {
    completion("This is a string which is an Any, so that's fine")
}

func someFunc<T: Any>(completion: (T) -> ()) {
    anotherFuncWith(completion: completion)
}

这无法像您的示例那样编译。现在让我们考虑一下如果它真的编译了我能做什么。我可以打电话给:
func complete(x: Int) -> () {
    print(x + 1)
}

someFunc(completion: complete)

所以现在Any调用anotherFuncWith传递一个无法添加的complete。撞车。
这里的根本问题是你已经倒退了。
我们怎么解决?取决于你真正的意思。这个密码有点奇怪。您是否关心String的实际类型?你好像从来没用过。如果你不在乎,那就使用协议:
public protocol MyPublicProtocol2 {
    func someFunc(completion: (MyPublicProtocol1) -> ())
}

如果您确实关心实际类型,请使用PAT:
public protocol MyPublicProtocol2 {
    associatedtype T: MyPublicProtocol1
    func someFunc(completion: (T) -> ())
}

或者你可能想重新考虑是否需要一个协议。我经常发现人们在还不需要协议的时候就可以达成协议。这些协议有多个实现吗?是否有多个类型被传递?如果没有,我会简化,并且只在您在当前代码中解决实际问题时使用泛型/协议。(你可能需要它们;这只是我的建议,许多人在过度设计时发现有用。)

10-08 14:55