【问题标题】:Unexpected non-void return value in void function, return multiple values [duplicate]void函数中出现意外的非void返回值,返回多个值[重复]
【发布时间】:2018-01-24 06:24:40
【问题描述】:

我创建的函数有问题,我想返回多个值,但似乎一直收到此错误

void 函数中出现意外的非 void 返回值

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double) -> (Double, Double, String) {

        let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL)
            .responseJSON { response in

                if let value = response.result.value {
                    let json = JSON(value)
                    let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                    let price = distance * 1.0 // Double
                    let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                    return (distance, price, duration) // Keep getting this error on this line
                }
        }


    }

我做错了什么?我返回了正确的数据类型。

【问题讨论】:

  • 我认为您需要使用完成处理程序。
  • 使用完成处理程序,不返回,你也没有在当前函数上返回任何东西,Alamorefire.request 在闭包中不返回任何东西

标签: ios swift alamofire


【解决方案1】:

这里的第一个错误是Alamofire.request... 是异步的。所以你不能返回在你的函数中使用它获取的值。

您收到错误的原因是因为您在尝试返回时不再在您的函数中。您在作为 Alamofire 请求的完成处理程序的函数中。

为了从中获得一些东西,您必须将其传递给您自己的完成处理程序。像这样……

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completionHandler: @escaping (Double, Double, String) -> ()) {

    let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL).responseJSON { response in
            if let value = response.result.value {
                let json = JSON(value)
                let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                let price = distance * 1.0 // Double
                let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                completionHandler(distance, price, duration) // Keep getting this error on this line
            }
        }
    }
}

签名(Double, Double, String) -> () 是一个接收两个Doubles 和一个String 的函数。当您从网络取回数据时,您将调用此函数。

那你可以这样称呼它……

calculateDistance(1, 2, 3) { (distance, price, duration) in
    // do something with the distance price and duration
}

这里只是另一个注意事项...使用_ 压缩函数中的参数名称是非常糟糕的做法。如果从函数名称中可以明显看出它是什么,则对第一个参数执行(也许),但不要对以下参数执行此操作。

【讨论】:

  • 感谢您的回答,但我不断收到错误fatal error: unexpectedly found nil while unwrapping an Optional value
  • 我试图打印出这些值,它显示了正确的数据。但是当我使用这个completionHandler时,它会返回一个错误
  • @sinusGob 意外发现 nil 是一个与此问题无关的完全不同的问题。有很多这样的问题在问这个问题。我建议先阅读一本关于 Swift 的书来学习基础知识。
  • 我明白你的意思,但是我运行了两个单独的函数,一个带有完成处理程序,一个没有完成处理程序,没有完成处理程序正确返回值但是当涉及到完成处理程序时它返回此错误跨度>
  • @sinusGob 意外发现 nil 是一个与此问题无关的完全不同的问题。有很多这样的问题在问这个。我建议先阅读一本关于 Swift 的书来学习基础知识。
【解决方案2】:

你需要使用块来返回值

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completion: @escaping (Double, Double, String)->()) {

        let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL)
            .responseJSON { response in

                if let value = response.result.value {
                    let json = JSON(value)
                    let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                    let price = distance * 1.0 // Double
                    let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                    completion(distance, price, duration) // return values
                }
        }


    }

要获得该值,请使用:

//call the method
 calculateDistance(SomeDouble, SomeDouble, SomeDouble, SomeDouble) {(distance, price, duration) in
         //here you can use those values
    }

【讨论】:

  • 你也可以让你的完成成为可选的。如果连接或接收到的值出现问题,它将允许您处理可能遇到的错误
【解决方案3】:

return 语句用于闭包,它是 Alamofire 请求的回调,而不是 calculateDistance 函数。当收到请求的响应时,将执行此闭包。由于请求是异步的,这个闭包会在你的函数calculateDistance返回很久之后执行。

相反,您可以使用委托模式或完成处理程序。

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completion: @escaping (Double, Double, String) -> ()) {
    Alamofire.request(...).responseJSON {
        parse response
        completion(distance, price, duration)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多