【问题标题】:Why SwiftUI's View Protocol use PAT?为什么 SwiftUI 的 View Protocol 使用 PAT?
【发布时间】:2019-10-24 10:35:38
【问题描述】:

View 协议定义如下:

public protocol View : _View {

    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required `body` property.
    associatedtype Body : View

    /// Declares the content and behavior of this view.
    var body: Self.Body { get }
}

所以View现在是PATed协议,不能直接作为返回类型,虽然swift 5.1的不透明返回类型可以处理这个,但是为什么要声明associatedtype Body : View,而不是直接声明var body: View { get } ?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    因为如果它只是一个var body: Self.Body { get } - 你的实体,实现View 协议,将不知道body 的类型。

    struct MyView: View {
        var body: MyAnotherView {
            //implementation...
        }
    }
    

    这段代码不会编译,你必须这样写:

    struct MyView: View {
        var body: View {
            //implementation...
        }
    }
    

    而且我认为在幕后 SwiftUI 必须知道 View 的确切类型,而不仅仅是协议

    【讨论】:

      【解决方案2】:

      在 SwiftUI 之前,Swift 不允许我们使用具有关联类型的协议作为返回类型,但我们可以使用“常规”协议。 编译器让您通过显示以下错误来限制:

      “协议只能用作通用约束,因为它具有 Self 或关联的类型要求。”

      什么意思?

      • 编译器无法从该定义中推断出关联类型,返回类型将不完整。

      • 每当我们调用那个函数时,它总是返回不同的具体类型,而不是相同的具体类型。

        • 编译器不允许您对这种具体类型执行交换、相等、比较操作。即使他们采用相同的协议(即 PAT)。 因为具体类型可能具有它们实现或使用的不同关联类型。

        为了避免在每次调用时将不同的具体类型作为返回类型,我们使用 some 关键字作为不透明的返回类型。

      不透明的返回类型:

      1. 它与泛型类型相反。
      2. 它总是返回相同的具体类型。你和编译器都知道。
      3. 如果我们改用不透明的结果类型,我们会强制该函数始终返回相同的具体类型。
      4. 内部函数在执行操作时我们知道泛型类型。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 2013-10-16
      • 2020-09-10
      • 1970-01-01
      • 2020-12-24
      • 2021-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多