Swift 传递协议一致性
Swift transitive protocol conformance
有人可以解释为什么下面的例子不能编译吗?我是否遗漏了一些微不足道的东西?
protocol Coordinator {}
protocol Coordinatable {
var coordinator: Coordinator { get set }
}
class ExampleCoordinator: Coordinator {}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator!
}
错误是:
Type 'ViewController' does not conform to protocol 'Coordinatable'
谢谢!
将 var coordinator: ExampleCoordinator!
替换为 var coordinator: Coordinator
。您正试图遵守 Coordinatable
因此您必须实现它的属性。
编辑:
import UIKit
protocol Coordinator {}
protocol Coordinatable {
var coordinator: Coordinator { get set }
}
class ExampleCoordinator: Coordinator {}
class ViewController: UIViewController, Coordinatable {
var coordinator: Coordinator
init(coordinator: Coordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
// ignore this, it has nothing to do with the question/answer
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let testVC = ViewController(coordinator: ExampleCoordinator()) // works
它不起作用的原因
假设您的代码可以工作并且我们另外编写
class ExampleCoordinator2: Coordinator {}
val viewController = ViewController()
viewController.coordinator = ExampleCoordinator2()
无法分配给 coordinator
,因为 ExampleCoordinator2
不是 ExampleCoordinator
的子类。
因此,仅考虑类型,以下代码应该可以工作但Swift编译器不允许(这可能会在未来工作):
protocol Coordinatable {
var coordinator: Coordinator { get } // removing the `set`
}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator! // still an error
}
可能的解决方案
在ViewController
中使用var coordinator: Coordinator
class ViewController: UIViewController, Coordinatable {
var coordinator: Coordinator
init(coordinator: Coordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在Coordinatable
中仅使用{ get }
protocol Coordinatable {
var coordinator: Coordinator { get } // removing the `set`
}
class ViewController: UIViewController, Coordinatable {
// computed property
var coordinator: Coordinator {
// implicit return
exampleCoordinator
}
var exampleCoordinator: ExampleCoordinator!
}
在Coordinatable
中使用associatedtype
protocol Coordinatable {
associatedtype C: Coordinator
var coordinator: C { get set }
}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator
init(coordinator: ExampleCoordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
然而,这有一个 很大的缺点 ,因为 Coordinatable
有一个 associatedtype
,所以你不能有一个类型为 [Coordinatable]
的异构数组。而且,您仍然不能分配 ExampleCoordinator2
.
类型的值
您只能在 <C: Coordinatable>
上编写通用代码。例如
func printCoordinators<C: Coordinatable>(coordinatables: [C]) {
coordinatables.forEach {
print([=15=].coordinator)
}
}
有人可以解释为什么下面的例子不能编译吗?我是否遗漏了一些微不足道的东西?
protocol Coordinator {}
protocol Coordinatable {
var coordinator: Coordinator { get set }
}
class ExampleCoordinator: Coordinator {}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator!
}
错误是:
Type 'ViewController' does not conform to protocol 'Coordinatable'
谢谢!
将 var coordinator: ExampleCoordinator!
替换为 var coordinator: Coordinator
。您正试图遵守 Coordinatable
因此您必须实现它的属性。
编辑:
import UIKit
protocol Coordinator {}
protocol Coordinatable {
var coordinator: Coordinator { get set }
}
class ExampleCoordinator: Coordinator {}
class ViewController: UIViewController, Coordinatable {
var coordinator: Coordinator
init(coordinator: Coordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
// ignore this, it has nothing to do with the question/answer
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let testVC = ViewController(coordinator: ExampleCoordinator()) // works
它不起作用的原因
假设您的代码可以工作并且我们另外编写
class ExampleCoordinator2: Coordinator {}
val viewController = ViewController()
viewController.coordinator = ExampleCoordinator2()
无法分配给 coordinator
,因为 ExampleCoordinator2
不是 ExampleCoordinator
的子类。
因此,仅考虑类型,以下代码应该可以工作但Swift编译器不允许(这可能会在未来工作):
protocol Coordinatable {
var coordinator: Coordinator { get } // removing the `set`
}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator! // still an error
}
可能的解决方案
在ViewController
中使用var coordinator: Coordinator
class ViewController: UIViewController, Coordinatable {
var coordinator: Coordinator
init(coordinator: Coordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在Coordinatable
中仅使用{ get }
protocol Coordinatable {
var coordinator: Coordinator { get } // removing the `set`
}
class ViewController: UIViewController, Coordinatable {
// computed property
var coordinator: Coordinator {
// implicit return
exampleCoordinator
}
var exampleCoordinator: ExampleCoordinator!
}
在Coordinatable
中使用associatedtype
protocol Coordinatable {
associatedtype C: Coordinator
var coordinator: C { get set }
}
class ViewController: UIViewController, Coordinatable {
var coordinator: ExampleCoordinator
init(coordinator: ExampleCoordinator) {
self.coordinator = coordinator
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
然而,这有一个 很大的缺点 ,因为 Coordinatable
有一个 associatedtype
,所以你不能有一个类型为 [Coordinatable]
的异构数组。而且,您仍然不能分配 ExampleCoordinator2
.
您只能在 <C: Coordinatable>
上编写通用代码。例如
func printCoordinators<C: Coordinatable>(coordinatables: [C]) {
coordinatables.forEach {
print([=15=].coordinator)
}
}