簡體   English   中英

具有關聯類型的協議繼承

[英]Protocol inheritance with associated type

我有一個描述路由器行為的基本協議:

protocol BaseRouterProtocol: AnyObject {
    associatedtype View: MainView
    func dismiss(viewController: ViewController<View>?)
}

extension BaseRouterProtocol {
    func dismiss(viewController: ViewController<View>?) {
        viewController?.navigationController?.popViewController(animated: true)
    }
}

我想采用這個協議到另一個這樣的:

protocol StartRouterProtocol: BaseRouterProtocol where View == StartView {
    func showTermsVC()
    func showSignInVC()
}

但是當我創建這種類型的變量時:

let router: StartRouterProtocol

編譯器給我一個錯誤:

協議 'StartRouterProtocol' 只能用作通用約束,因為它具有 Self 或相關的類型要求

如果我描述了我期望的類型,為什么會發生這種情況?

一旦協議具有關聯類型,該協議就不能單獨用作實例聲明的類型——僅用於泛型約束和聲明一致性。

所以在這種情況下,Swift 會說“是的,但是StartRouterProtocol的關聯類型的具體類型是什么?”

在這種情況下,它要求您:

  1. 直接使用具體類型,即let router: MyStartViewClass與此一致性聲明,別處: class MyStartViewClass: StartRouterProtocol { ... } )
  2. 或者,將具體類型的需求向上推一層,作為通用約束,
class MyRouterController<T: StartRouterProtocol> {
    let router: T
}

這可能不是您所希望的,但不幸的是,關聯類型增加了您使用協議的復雜性,尤其是當您熟悉其他語言的泛型和接口時。 (即 Java/C# 接口)

您可以通過使用稱為“類型擦除”的概念來解決關聯類型的某些方面——但這可能會導致其他問題和復雜性。

以下是一些可能有幫助的進一步閱讀: https : //medium.com/monstar-lab-bangladesh-engineering/swift-from-protocol-to-relatedtype-then-type-erasure-a4093f6a2d08

暫無
暫無

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

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