在 Swift 中强制转换 CLLocationDistance

Posted

技术标签:

【中文标题】在 Swift 中强制转换 CLLocationDistance【英文标题】:Casting CLLocationDistance in Swift 【发布时间】:2015-01-03 05:06:12 【问题描述】:

我是一个使用 Swift 的完全新手,我在尝试做一些应该很简单的事情时感到头疼。

我有一个对象 Place ,它有一个 Double 类型的变量,称为距离。我正在使用以下代码来存储用户位置与其他一些位置之间的距离:

var obj = res as Place
let loc = CLLocation(latitude: obj.location.lat, longitude: obj.location.lng)
let dist = CLLocation.distanceFromLocation(loc)
obj.distance = dist // ERROR 

最后一行向我显示一条错误消息“CLLocationDistance 不可转换为'Double'”。据我所知,CLLocationDistance 应该是 Double。我尝试使用

将该值转换为 double 和 float
Double(dist)

obj.distance = dist as Double

但似乎没有任何效果。我将不胜感激。

【问题讨论】:

您的代码没有意义 distanceFromLocation 不是 CLLocation 上的类方法 - 它是一个实例方法,因此您需要在现有的 CLLocation 对象上调用它。 Place的定义是什么? distance 是如何声明的? CLLocationDistance 被定义为typealias CLLocationDistance = Double,所以它们是完全等价的,也就是说你还有其他问题。 是的,你是对的。问题是我使用这种方法是错误的。距离被定义为 Double 但显然,该方法不打算像我那样使用。 Gregory Higley 的回答完美地描述了这种情况。 【参考方案1】:

发生这种情况的原因归结为以下几行:

let distance = CLLocation.distanceFromLocation(loc)

这不是在做你认为它在做的事情。 distanceFromLocation 是一个实例方法,但您将其作为类方法调用。与 ObjC 不同,Swift 允许这样做,但您实际上得到的不是CLLocationDistance,而是具有以下类型签名的函数:CLLocation -> CLLocationDistance。您可以通过自己添加类型注释来验证这一点:

let distance: CLLocation -> CLLocationDistance = CLLocation.distanceFromLocation(loc)

这称为部分应用程序,超出了我的回答范围,除了要注意分配给distance 的函数的第一个参数在作为实例方法调用时将是隐式的self

修复很简单:

let distance = loc.distanceFromLocation(loc)

那么一切都会如你所愿,至少从类型系统的角度来看是这样,因为这会正确返回一个CLLocationDistance,它可以替代Double

【讨论】:

很好的答案,格雷戈里。非常感谢。【参考方案2】:

您需要两个具有两个不同位置的 CLLocation 对象

fromLocationtoLocation

然后你会得到距离

let distance = fromLocation.distanceFromLocation(toLocation)

新旧位置距离的代码示例:

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) 
    if let firstLocation = locations.first as? CLLocation
    
        mapView.setCenterCoordinate(firstLocation.coordinate, animated: true)

        let region = MKCoordinateRegionMakeWithDistance(firstLocation.coordinate, 1000, 1000)
        mapView.setRegion(region, animated: true)

        if let oldLocation = oldLocation 
            let delta: CLLocationDistance = firstLocation.distanceFromLocation(oldLocation)
            totalDistane += delta
            updateDistanceLabel()
        

        oldLocation = firstLocation
    

【讨论】:

谢谢你,Ashish。这不是我问题的真正答案,但绝对是一个不错的选择。

以上是关于在 Swift 中强制转换 CLLocationDistance的主要内容,如果未能解决你的问题,请参考以下文章

Swift:在运行时在非可选中检测到意外的 nil 值:强制转换为可选失败

为啥 Swift4 会强制转换 UIButton 数组!到 [UIButton?] 类型?

如何使用警卫同时解开 Swift 可选和强制类型转换?

Swift 3:从“UIView”隐式强制表达的表达式?去任何

将 NSPersistentStoreResult 强制转换为数组

如何在 Swift 中将 NSDateComponents 转换为 DateComponents