SwiftUI 什么是 “some “关键字
SwiftUI中的 “some “关键字用于表示一个类型符合某个协议,但没有指定具体的一致性。AnyView类型是一种类型消除的视图,可以表示符合View协议的任何视图,通常与它联系使用。
SwiftUI 将一些视图定义为一种类型,在不确定具体视图类型的情况下,可以代表符合视图协议的任何视图。这使得代码更加通用和适应。
换句话说,一些关键字被用来声明不透明的类型。在Swift 5.1版本中,这是以对不透明返回类型的支持引入的。
什么是不透明类型?
当你使用不透明类型时,这意味着你可以声明预期的返回类型,而不需要定义一个确切的类型。
例如,你可以使用一些视图来创建一个可以容纳任何视图的变量,而不知道该视图的具体类型。下面是一个例子。
let anyView: some View = Text("Hello, World!")
这就创建了一个名为anyView的变量,可以容纳任何符合View协议的视图,并将其赋值为显示字符串 “Hello, World!”的文本视图。
为了创建一个可以容纳任何符合协议的类型的变量而不知道它将携带的特定类型,一些关键字被用作类型约束。
返回不透明的类型而不匹配准确的类型
如果我们不返回确切的类型,会发生什么?在这种情况下,你会得到一个像下面这样的错误。
例子
一个包含该错误的代码例子看起来如下
import SwiftUI
func makeHeaderView(isProUser: Bool) -> some View {
if isProUser {
return Text("You have a premium membership !!") // return type is Text
} else {
return VStack { // Return type is VStack)>>
Text("Do you want to become a PRO user?")
Button("Become PRO", action: {
// write action code
})
}
}
}
输出
这段代码会给你一个错误,看起来像这样。
error: function declares an opaque return type 'some View', but the return statements in its body do not have matching underlying types
正如你在上面的代码中看到的,我们正在返回两种类型的数据。为专业用户返回一个文本,为非高级用户返回一个VStack。
在这种情况下,编译器想通过 “some “关键字了解底层的具体类型。为了在同一方法的范围内返回不同的类型,不透明的类型必须被固定在值的范围内。
我们可以通过使用一个包装容器来解决上述代码,比如VStack --
import SwiftUI
func makeHeaderView(isProUser: Bool) -> some View {
VStack {
if isProUser {
Text("You have a premium membership !!") // return type is Text
} else {
Text("Do you want to become a PRO user?")
Button("Become PRO", action: {
// write action code
})
}
}
}
我们添加了一个额外的容器,只有在isProUser属性返回真时才需要。与其在上面的代码中使用结果生成器,不如使用@ViewBuilder属性重写它–
import SwiftUI
@ViewBuilder
func makeHeaderView(isProUser: Bool) -> some View {
if isProUser {
Text("You have a premium membership !!") // return type is Text
} else {
Text("Do you want to become a PRO user?")
Button("Become PRO", action: {
// write action code
})
}
}
结论
总之,SwiftUI中的 “some “关键字被用来告诉编译器返回类型,而不告诉返回视图的确切类型。通过这种方式,你可以隐藏关键信息。
为了返回 “some “类型,你可以使用包装器作为一个容器。另外,你可以使用@ViewBuilder属性来代替结果生成器。