我对我创建的函数有问题,我想返回多个值,但似乎,我一直收到此错误
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
}
}
}
我做错了什么?我返回正确的数据类型。
答案 0 :(得分:3)
这里的第一个错误是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
}
这里只是另一个注意事项......使用_
压缩函数中的参数名称是非常糟糕的做法。对于第一个参数(如果从函数名称中显而易见)它是什么(可能),但不要对以下参数执行此操作。
答案 1 :(得分:0)
您需要使用块来返回值
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
}
答案 2 :(得分:0)
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)
}
}