簡體   English   中英

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()

由於ExampleCoordinator2不是ExampleCoordinator的子類,因此無法分配給coordinator

因此,僅考慮以下代碼應該可以工作的類型但 Swift 編譯器不允許它(這可能在未來工作):

protocol Coordinatable {
    var coordinator: Coordinator { get } // removing the `set`
}

class ViewController: UIViewController, Coordinatable {
    var coordinator: ExampleCoordinator! // still an error
}

可能的解決方案

使用var coordinator: Coordinator ViewController中的 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]類型的異構數組,因為Coordinatable有一個associatedtype 而且,您仍然不能分配ExampleCoordinator2類型的值。

您只能在<C: Coordinatable>上編寫通用代碼。 例如

func printCoordinators<C: Coordinatable>(coordinatables: [C]) {
    
    coordinatables.forEach {
        print($0.coordinator)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM