无法使用 SwiftUI 推断复杂闭包 return 类型

Unable to infer complex closure return type with SwiftUI

按照 Apple 关于 SwiftUI 的教程的第 3 部分,Handling User Input,我收到此错误:

Unable to infer complex closure return type; add explicit type to disambiguate

我使用的是与教程相同的代码(即使是 'Complete' 示例代码也无法解决错误)。

有人知道这里出了什么问题吗?

struct LandmarkRow: View {
    var landmark: Landmark

    var body: some View {
        HStack {
            landmark.image(forSize: 50)
            Text(verbatim: landmark.name)
            Spacer()

            if landmark.isFavorite {
                Image(systemName: "star.fill")
                    .imageScale(.medium)
            }
        }
    }
}

不管问题的原因是什么,你怎么能在这里添加一个明确的类型来消除歧义?在这种情况下 return 类型是什么?

--

更新

显然你不应该用第三个教程继续第二个教程的结果。本教程中未记录的教程之间发生了一些变化。我已将项目文件添加到 Github,因此您可以 check out the diff.

最好下载 3rd tutorial 的项目文件来重新开始第 3 个教程。

问题不在于关闭,而在于地标上的 isFavorite 属性。

它没有在 Landmark 类型上声明,编译器没有显示未声明的 属性 错误,无法解析堆栈构建闭包 return 类型,所以它显示和那里的错误。

出色的 Apple 教程编写者和更好的 Xcode11 编译器。

修复:

  1. Landmark 类型上声明 isFavorite 变量。
  2. 确保使用 isFavorite = false 条目更新每个地标记录的 landmarkData.json,否则应用程序将在运行时崩溃。

这个问题的一些背景知识

就像@dirtydanee 已经回答的那样,这两个教程之间存在差异。但问题背后的问题是,虽然看起来你在做配置,但实际上只是函数嵌套在使用泛型和协议的函数中 "magically" 将所有内容解析为编译函数。

然而,对这些泛型和协议的一致性需要非常精确,因为否则整个函数树将无法再编译。但是很难为编译器确定什么一致性实际上失败了。这就是为什么您在顶部而不是实际发生的地方看到错误的原因。

强烈建议确保将您的视图分解为自然和简单的块,这样您就不会倾注数百行 View 代码来发现一个错误。

Dave DeLong had a really great talk 关于如何从 ViewController 组合视图直到今天仍然适用:基本上您永远不会将 View 用作另一个 View 中的子视图,但您需要将 View 分解为许多简单的 View。否则这些错误会让你抓狂。

对于在 SwiftUI 上遇到此错误并正在寻找调试视图堆栈的方法的人

此错误主要发生在一个子视图上存在编译问题时。

1 - 确保您的父视图可以支持多个子视图(VStack、ZStack)并且您的子视图少于 10 个。有时您可能想添加一个组包装器。

2 - 如果这不是问题,则可能是一个子视图有问题。尝试隔离您怀疑有问题的那个。通常我将子视图复制到 属性 并出现不同的错误

var debug: some View {
        MyViewWithError(property: self.property)
}

大多数时候您会遇到这种情况,因为您传递的是 属性 (self.property) 而不是绑定 (self.$property)

希望这可以帮助一些人

我 运行 打错了这个错误。当代码有语法问题时也会出现此错误。只需检查您的更改是否正确

我在一个子视图中遇到了问题,其中 @Binding prop 是不同类型的 @Binding 源。