Swiftui 为什么“ViewModifier”协议有“associatedtype”和“typealias”?

Swiftui 为什么“ViewModifier”协议有“associatedtype”和“typealias”?,swiftui,swift-protocols,type-alias,associated-types,Swiftui,Swift Protocols,Type Alias,Associated Types,据我所知,协议的定义如下: 协议视图修改器{ //传递给正文()的内容视图类型 类型别名内容 //body()返回的视图类型 associatedtype主体:视图 //唯一要求 func body(内容:Self.content)->Self.body } 我的问题是: 为什么Self.Content是typealias而Self.Body是associatedtype? 有什么不同吗? typealias仅更改类型的名称。没别的了 associatedtype是在协议实现中包含泛型的一种

据我所知,协议的定义如下:

协议视图修改器{
//传递给正文()的内容视图类型
类型别名内容
//body()返回的视图类型
associatedtype主体:视图
//唯一要求
func body(内容:Self.content)->Self.body
}
我的问题是:

为什么
Self.Content
typealias
Self.Body
associatedtype
? 有什么不同吗?

  • typealias
    仅更改类型的名称。没别的了

  • associatedtype
    是在协议实现中包含泛型的一种方法


在上面的示例中,
Body
是符合
View
的具体类型,由
Body(内容:)
返回类型推断


Content
只是作为
Content
参数传递的类型的另一个名称


rob mayoff以更详细的方式解释了
ViewModifier

这告诉我们,当我们编写自己的
ViewModifier
时,我们的
主体
方法将接收某种类型的
视图
(具体类型由 框架,我们可以将其称为
Content
),并返回某种排序 查看(我们可以选择具体的退货类型)

这意味着你不知道什么是
内容
,你只需要对它进行操作-为了方便起见,它被称为
内容
,因此你不必处理
\u ViewModifier\u内容

为什么
Self.Content
typealias
Self.Body
associatedtype
?有什么区别

由于
Content
是一个
typealias
,因此
ViewModifier
协议的作者在编写协议时可以选择要使用别名的类型。(您无法看到该类型的别名,因为该类型是
\u ViewModifier\u Content
。当SDK中的标识符以
\u
开头时,Apple会从文档和生成的界面中忽略该标识符。)

因为
Body
是一个
associatedtype
当您编写一个符合
ViewModifier
协议的类型时,您可以选择它别名的类型。您可以根据两个条件将
Body
设置为您想要的任何类型:

  • 您必须选择符合
    视图
    的类型(因为
    视图修改器
    协议约束
    主体
    以符合
    视图

  • 您必须能够创建或获取所选类型的实例,因为您必须从
    body
    方法返回它的实例。(或者你可以撞车或吊死以避免返回,但这通常不是你想要的…)

因此,当您实现符合
ViewModifier
的类型时,您无法影响
内容的含义。它的意思总是
\u ViewModifier\u Content
。但是您可以通过选择
Body
方法的返回类型来选择
Body
的含义

这里我将强制
Body
表示
清空视图

struct EmptyModifier: ViewModifier {
    func body(content: Content) -> EmptyView {
        EmptyView()
    }
}
这里我将强制
Body
表示
Color

struct RedModifier: ViewModifier {
    func body(content: Content) -> Color {
        Color.red
    }
}
通常我们使用
some View
作为类型,这意味着Swift会为我们推断出确切的类型,并将其保密:

struct FrameModifier: ViewModifier {
    var color: Color
    var width: CGFloat

    func body(content: Content) -> some View {
        return content
            .padding(width)
            .border(color, width: width)
    }
}

在这里,我们所知道的关于
主体
类型的所有信息是它符合
视图
。Swift极力阻止我们在编译时找出真正的类型。

Body
将从您的返回中推断出来,因此它是关联类型,
内容
将提供给您,它由ViewModifier知道(因为它生成),但为您隐藏,typealias也是如此。associatedtype是在协议实现中包含泛型的一种方法,它只是包含另一个类型类/协议的一种方法。e、 g.您也可以使用非协议的
UIView
Content
只是谁的另一个名字<代码>视图
?还是别的什么?你能举个具体的例子,告诉我
内容的具体类型是什么吗?尽管你提供了详细的信息,但有一点我还是不太明白。据我所知,我们不必指定
body()
方法返回的类型,SwiftUI将为我们推断。在这种情况下,为什么不将
Body
也设为
typealias
呢?协议完全定义了
typealias
,但只限制了
关联类型的定义。然后,每个一致性都以自己的方式完全定义了
关联类型
。这是
类型别名
关联类型
之间的区别。My
EmptyModifier
RedModifier
FrameModifier
示例是三种不同的符合性。每个一致性定义了不同的
主体
。如果
Body
typealias
,它将由
ViewModifier
完全定义,我的三个符合性不能给出三个不同的定义。
struct FrameModifier: ViewModifier {
    var color: Color
    var width: CGFloat

    func body(content: Content) -> some View {
        return content
            .padding(width)
            .border(color, width: width)
    }
}