Ios void函数中意外的非void返回值,返回多个值

Ios void函数中意外的非void返回值,返回多个值,ios,swift,alamofire,Ios,Swift,Alamofire,我对我创建的函数有一个问题,我想返回多个值,但似乎,我一直得到这个错误 void函数中意外的非void返回值 我做错了什么?我返回正确的数据类型。您需要使用块返回值 func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completion: @escaping (Double, Double, String)->()) {

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

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


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

您需要使用块返回值

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
    }

return语句用于闭包,闭包是Alamofire请求的回调,而不是
calculateInstance
函数。当收到请求的响应时,执行此关闭。由于请求是异步的,因此此闭包在函数
calculateInstance
返回很久之后执行

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

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

这里的第一个错误是,
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)->()
是一个包含两个
Double
和一个
字符串的函数。当您从网络中获取数据时,您将调用此函数

那么你会把它叫做

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

这里还有一张便条。。。使用
\uuu
挤压函数中的参数名称是一种非常糟糕的做法。如果从函数名可以明显看出第一个参数是什么,那么就对其执行(可能),但不要对以下参数执行此操作。

我认为您需要使用完成处理程序。使用完成处理程序,而不是返回,并且您也不会返回当前函数的任何内容,
Alamorefire.request
不要在closure中返回任何内容,您也可以选择是否完成。如果连接或接收到的值出现问题,它将允许您处理可能出现的错误感谢您的回答,但我不断收到错误
致命错误:在展开可选值时意外发现nil
我试图打印出值,它显示了正确的数据。但是当我使用这个completionHandler时,它返回一个error@sinusGob出乎意料地发现,零是一个完全不同的问题,与这个问题无关。有很多问题在问这个。我建议先读一本关于Swift的书来学习基础知识。我明白你的意思,但我运行两个单独的函数,一个带完成处理程序,另一个不带完成处理程序,如果没有完成处理程序,则正确返回值,但当涉及到completionHandler时,它将返回此值error@sinusGob出乎意料地发现,零是一个完全不同的问题,与这个问题无关。有很多这样的问题问这个。我建议先读一本关于斯威夫特的书来学习基础知识。
calculateDistance(1, 2, 3) { (distance, price, duration) in
    // do something with the distance price and duration
}