Swift 快速变异函数struct pass struct’;函数中的变量名是什么?

Swift 快速变异函数struct pass struct’;函数中的变量名是什么?,swift,struct,parameter-passing,mutating-function,Swift,Struct,Parameter Passing,Mutating Function,我在Swift工作,试图更新一个需要保持经度和纬度的组织结构。我在结构中创建了一个mutating函数,它将根据组织结构的地址更新纬度和经度。我让它工作了,但问题是当我调用mutating函数时,我需要手动输入带有.lation和.longitude的变量名。是否有一种方法可以自动传递变量struct的名称并引用.lation和.longitude,而无需调用特定的变量名,从而使其更可用?我在下面的代码中包含了一个示例。谢谢你的帮助 import UIKit import PlaygroundS

我在Swift工作,试图更新一个需要保持经度和纬度的组织结构。我在结构中创建了一个mutating函数,它将根据组织结构的地址更新纬度和经度。我让它工作了,但问题是当我调用mutating函数时,我需要手动输入带有.lation和.longitude的变量名。是否有一种方法可以自动传递变量struct的名称并引用.lation和.longitude,而无需调用特定的变量名,从而使其更可用?我在下面的代码中包含了一个示例。谢谢你的帮助

import UIKit
import PlaygroundSupport
import CoreLocation

PlaygroundPage.current.needsIndefiniteExecution = true

struct organization {
    var name: String
    var address: String
    var latitude: CLLocationDegrees = 0 //default setting for latitude
    var longitude: CLLocationDegrees = 0 //default setting for longitude
    
    mutating func getCoordinateFrom(completion: @escaping(_ coordinate: CLLocationCoordinate2D?, _ error: Error?) -> () ) {
        CLGeocoder().geocodeAddressString(address) { placemarks, error in
            completion(placemarks?.first?.location?.coordinate, error)
        }
    }
}

struct Coordinates {
    var latitude: Double
    var longitude: Double
}

//create an wildernessLodge variable of type organization
var wildernessLodge = organization(name: "Disney's Wilderness Lodge", address: "901 Timberline Dr, Orlando, FL 32830")

wildernessLodge.getCoordinateFrom { coordinate, error in
    guard let coordinate = coordinate, error == nil else { return }
    wildernessLodge.latitude = coordinate.latitude
    wildernessLodge.longitude = coordinate.longitude
    print("update 1 \(wildernessLodge)")
    }


我被你的代码弄糊涂了。为什么
getCoordinateFrom
被标记为
变异
?也许你是想写这样的东西

init(name: String, address: String) {
    self.name = name
    self.address = address
    CLGeocoder().geocodeAddressString(address) { placemarks, error in
        guard let coordinate = placemarks?.first?.location?.coordinate, error == nil else { return }
        self.latitude = coordinate.latitude
        self.longitude = coordinate.longitude
    }
}
mutating func getCoordinates fromAddress(){
CLGeocoder().geocodeAddressString(address){placemarks,中有错误
guard let坐标=placemarks?.first?.location?坐标,错误==nil else{return}
self.latitude=坐标.latitude
self.longitude=坐标经度
}
}
现在这个函数正在变异(它修改了self),并且

wildernessLodge.getCoordinateFrom{coordinate,错误在…}
可以替换为

wildernessLodge.getCoordinates fromAddress()
离开
getCoordinateFrom
方法的唯一原因是,在代码中的某个地方,您希望从地址获取坐标,但不更新结构中的坐标。我想不出这样做的好理由,所以我建议用其他方法替换
getCoordinateFrom
方法

可选地,如果您通常打算在创建这种类型的值之后设置坐标,那么您可能需要考虑这样的事情。

init(name: String, address: String) {
    self.name = name
    self.address = address
    CLGeocoder().geocodeAddressString(address) { placemarks, error in
        guard let coordinate = placemarks?.first?.location?.coordinate, error == nil else { return }
        self.latitude = coordinate.latitude
        self.longitude = coordinate.longitude
    }
}

然后,您可以使用
组织(名称:名称,地址:地址)
创建
组织
,坐标将自动正确设置

如果这两个都不令人满意,那么您可能应该创建两个不同的结构来捕获所需的行为

struct组织{
变量名称:String
变量地址:字符串
func with coordinates(完成:@escaping(uu坐标:CLLocationCoordinate2D?,u错误:error?->()){
CLGeocoder().geocodeAddressString(address){placemarks,中有错误
完成(位置标记?第一?位置?坐标、错误)
}
}
}
带坐标的结构组织{
变量名称:String
变量地址:字符串
变量纬度:CLLocationDegrees
变量经度:CLLocationDegrees
初始化(来自组织:组织){
self.name=organization.name
self.address=organization.address
organization.withCoordinates{coordinate,中有错误
guard let坐标=坐标,错误==nil else{return}
self.latitude=坐标.latitude
self.longitude=坐标经度
}
}
} 
我更喜欢这样的方法,但我喜欢有很多类型

最后,正如评论中指出的,如果你真的只关心简洁,你可以替换

var纬度:CLLocationDegrees
变量经度:CLLocationDegrees

var坐标:CLLocationCoordinate2D
变量纬度:CLLocationDegrees{coordinates.latitude}
变量经度:CLLocationDegrees{coordinates.longitude}
然后更换

Wildernesslovge.latitude=坐标.latitude
wildernessLodge.longitude=坐标.longitude

Wildernesslovge.coordinates=坐标
事实上,您可以随意组合这些方法中的任何一种

编辑:正如所指出的,这些解决方案不能按原样工作。基本的紧张局势是试图与
CLGeocoder
的异步方法同步工作。一种解决方案是使用类而不是结构。另一种方法是使用上述
with coordinate
方法的修改:

struct组织{
变量名称:String
变量地址:字符串
func withCoordinate(回调:@escaping(OrganizationWithCoordinate?,错误?->Void){
CLGeocoder().geocodeAddressString(self.address){placemarks,中有错误
如果let坐标=placemarks?first?location?坐标,则错误==nil{
设orgWithCoord=OrganizationWithCoorde(名称:self.name,地址:self.address,纬度:坐标.纬度,经度:坐标.纬度)
回调(orgWithCoord,无)
}否则{
回调(无,错误)
}
}
}
}
带坐标的结构组织{
变量名称:String
变量地址:字符串
变量纬度:CLLocationDegrees
变量经度:CLLocationDegrees
}
组织机构(名称:“迪士尼荒野小屋”,地址:“901 Timberline Dr,佛罗里达州奥兰多,邮编32830”)。坐标为{orgWithCoord,错误为
guard let orgWithCoord=orgWithCoord,错误==nil else{
打印(“错误”)
返回
}
打印(orgWithCoord)
}
这包含了
CLGeocoder
的异步特性

另一种解决方案是使用
DispatchSemaphore
强制
CLGeocoder
同步,如下所示。我认为这些在操场上不能正常工作,但在实际应用中应该可以正常工作

struct组织{
变量名称:String
变量地址:字符串
变量纬度:CLLocationDegrees
变量经度:CLLocationDegrees
init(名称:String,地址:String)抛出{
self.name=名称
self.address=地址
变量tempCoordinate:CLLocationCoordinate2D?
错误?
让sema=DispatchSemaphore(值:0)
CLGeocoder()。