【发布时间】:2022-11-27 12:08:20
【问题描述】:
我想使用这样的东西,但我不明白为什么它不起作用:
protocol InitProtocol {
init()
}
protocol SomeServiceProtocol: InitProtocol {}
class SomeManager {
func initService<T: InitProtocol>(type: T.Type) -> T {
type.init()
}
}
class SomeViewModel {
let someService: SomeServiceProtocol
init(someService: SomeServiceProtocol = SomeManager().initService(type: SomeServiceProtocol.self)) {
self.someService = someService
}
}
SomeViewModel 初始化中的依赖项注入抛出一个错误:"Type 'any SomeServiceProtocol' cannot conform to 'InitProtocol'"
SomeServiceProtocol清楚做符合InitProtocol,所以我假设编译器真正在说的是因为类型T在通用函数initService()中被声明为符合InitProtocol,任何试图使用返回对象的东西都只会识别它作为 InitProtocol 的一个实例,而不是传入的内容。有没有办法解决这个问题?
笔记
下面的代码编译得很好,但它不允许我初始化T。
class SomeManager {
func initService<T>(type: T.Type) -> T? {
nil
}
}
class SomeViewModel {
let someService: SomeServiceProtocol
init(someService: SomeServiceProtocol = SomeManager().initService(type: SomeServiceProtocol.self)!) {
self.someService = someService
}
}
【问题讨论】:
-
需要明确的是,一个协议不能符合另一个协议,但它可以扩展它(继承自)所以 SomeServiceProtocol 扩展了 InitProtocol。
-
您需要将真实类型传递给 initService 调用而不是协议
-
initService以具体类型作为参数,协议不是具体类型,协议是存在类型。在尝试随机示例之前了解协议和泛型可能会有所帮助 -
@JoakimDanielson 感谢您的回答。我在底部添加了一个注释来概述什么是有效的。您知道是否有一种方法可以实现在 func 中初始化泛型类型并返回它?
-
你可以用
class SomeViewModel<M : SomeServiceProtocol> { let someService: M和SomeManager().initService(type: M.self)来做,但是你不能通过一个协议。在 Swift 5.7 中,有一个新的语法some SomeServiceProtocol,它实际上与受协议约束的泛型相同。
标签: swift generics protocols swift-protocols