SwiftUI 如何修复“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”

Posted

技术标签:

【中文标题】SwiftUI 如何修复“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”【英文标题】:SwiftUI How to fix "Unable to infer complex closure return type; add explicit type to disambiguate" 【发布时间】:2020-03-28 08:48:49 【问题描述】:

我不知道如何修复此错误“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”。我已经尝试了everythink(我能做到的)并且不起作用

import SwiftUI  

struct ContentView: View   

    @State var content: String = "start"  


    var body: some View   

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

            self.content = try! String(contentsOf: URL(string: "http://zyglarski.pl/swift-http-docs/tinder_list.php")!)  

            var contentData = self.content.data(using: .utf8)  
            var jsDec = JSONDecoder()  
            var responce = try! jsDec.decode(Candidates.self, from: contentData!)  

            Text(responce)  
          
      
  

struct ContentView_Previews: PreviewProvider   
    static var previews: some View   
        ContentView()  
      
  


struct Candidates: Codable   
    let candidates:[Candidate]  
  
struct Candidate: Codable   
    let filename: String  
    let name: String  
    let age: String  
    let distance: String  
    let match: String  
 

请帮忙

【问题讨论】:

【参考方案1】:

作为克里斯回答的补充:

让我们来看看闭包。一个“正常”的闭包,我们可以看到 .map ... 带有数组,它对列表的每个元素应用一个函数,并返回一个带有结果的新列表,如下所示:

let myArray = [1, 2, 3, 4, 5]
let tenTimes = myArray.map  (element) -> (Int) in
    return element * 10

// tenTimes is [10, 20, 30, 40, 50]

(element) -> (Int) in 的意思是:我们得到一个参数并将其命名为element,这样我们就可以在闭包中使用它,闭包的返回类型是Int

通常,我们对那一小段代码的第二行使用速记版本:

let tenTimes = myArray.map  element in

在这种情况下,Swift 可以推断出返回类型。

但是从(我相信)Swift 5.1 开始,有一个新规则:当函数/变量/闭包的内容只有一行代码时,我们不需要显式写@987654329这个词@. 所以在上面的例子中,我们也可以说:

tenTimes = myArray.map  element in
    element * 10

您在 SwiftUI 中看到的几乎每个 都意味着您正在使用闭包。关于 return 关键字的最后一条规则在 SwiftUI 中经常应用。

但还有别的:SwiftUI 中的闭包是特殊的 @ViewBuilder 闭包。因此,您可以将多个 View 放在另一个 View 中,就像在其中拥有多个 returns 的函数一样。但是当你使用其他代码时,比如let 语句,事情就会变得一团糟。 SwiftUI 不明白你想要什么。 有时你可以通过使用显式的return 来帮助它一点,但通常错误只是转移到另一个地方。有一个机会,经过大量的困惑,你会得到它的工作,但我可以向你保证,它不会是漂亮的代码。因此,我会选择 Chris 的解决方案。

Edit 2021:我对“具有多个返回语句的函数”很幼稚。更复杂的事情正在发生。该视频解释了究竟是什么:https://developer.apple.com/videos/play/wwdc2021/10253/ 这也可以澄清为什么将其他语句放在这些特殊闭包中不起作用。


如果你想了解更多关于闭包的信息,这里是官方文档的链接:https://docs.swift.org/swift-book/LanguageGuide/Closures.html。非常有趣,但信息量很大!

【讨论】:

【参考方案2】:

请阅读 swiftui 初学者教程,因为你犯了很多初学者错误。

如果需要快速帮助,请查看:

struct ContentView: View 


    @State var content: String = "start"
    @State var responce : String = ""
    @State var candidates : Candidates = Candidates(candidates: [])

    var body: some View 

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



            Text(responce)
                .onAppear() 
                    self.content = try! String(contentsOf: URL(string: "http://zyglarski.pl/swift-http-docs/tinder_list.php")!)

                    var contentData = self.content.data(using: .utf8)
                    var jsDec = JSONDecoder()
                    self.candidates = try! jsDec.decode(Candidates.self, from: contentData!)
            

        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    



struct Candidates: Codable 
    let candidates:[Candidate]

struct Candidate: Codable
    let filename: String
    let name: String
    let age: String
    let distance: String
    let match: String

【讨论】:

最好让他知道自己的错误,让他从中吸取教训 我知道,但它看起来像是他的第一个 swiftui 项目,有时我们都希望成功(yippie,它正在运行),因为我们不知道错误是什么......我已经告诉他阅读初学者教程,我厌倦了解释非常基本的事情,比如你不能在体内编写代码......等等

以上是关于SwiftUI 如何修复“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 SwiftUI 中的 navigationTitle 和工具栏之间的布局冲突?

SwiftUI:如何在 UIViewRepresentable UITextField 上调用 becomeFirstResponder 时修复“通过属性检测到的 AttributeGraph 循环”

SwiftUI 如何修复“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”

如何修复适用于 SwiftUI 中文本的动画制作帧问题/错误?

如何修复 TextField Binding <String> 以在 SwiftUI 中显示和编辑

如何使用 SwiftUI 中的图像修复 NavigationView 列表行中增加的高度"