【问题标题】:Swift EXC_BAD_INSTRUCTION on call to typealias / typed / defined closure w/o compiler error or warningSwift EXC_BAD_INSTRUCTION on call to typealias / typed / defined closure w/o compiler error or warning
【发布时间】:2015-02-02 17:52:41
【问题描述】:

给定一个结构、一个类和类型闭包:

struct Vector3d {
    var X:Double
    var Y:Double
    var Z:Double
}

class Sprite {

    var mass: Double = 0.0

    init(mass: Double) {
        self.mass = mass
    }
}

typealias ForceComputation =
    (NSTimeInterval, Sprite) -> Vector3d?

以下代码因EXC_BAD_INSTRUCTION而崩溃:

// Construct an instance of the class to call back with
var ball = Sprite(mass: 3.0)

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d in
    // use this line to close ball so it's available in debugger
    var mass1 = ball.mass

    // use mass1 in following line to ensure not optimized out
    // (ignore invalid gravity formula)
    var verticleAcceleration = -9.8 * projectile.mass * mass1

    return Vector3d(X:0.0, Y:verticleAcceleration, Z:0.0)
}

// activate the closure
gravity(ball)

调试器显示projectileball 的两个不同值。 projectile 中的字段mass 无效。但是mass 对闭包内部和外部的ball 都有效。没有编译器错误或警告但在执行projectile.mass 时抛出EXC_BAD_INSTRUCTION

尽管有误导性的调试数据,但问题与ForceComputation 闭包的参数无关。问题是返回的结构在typealias 中定义为可选:

typealias ForceComputation =
    (Sprite) -> Vector3d?

但使用非可选返回类型构造(注意Vector3d 之后缺少?):

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d in
    ....
}

更改上面的代码以删除打字:

// Create an instance of closure
var gravity = { (projectile:Sprite) -> Vector3d in
    ....
}

将修复代码或确保返回类型是可选的(注意Vector3d 之后的?):

// Create an instance of closure
var gravity:ForceComputation = { (projectile:Sprite) -> Vector3d? in
    ....
}

也会使这项工作。我的问题是,如果这是一个编译器错误,是否应该向 Apple 报告,或者是否有原因 EXC_BAD_INSTRUCTION 抛出的代码应该编译?

【问题讨论】:

    标签: swift compiler-bug


    【解决方案1】:

    这是一个编译器错误(已通过 Twitter here 确认),但已经存在许多关于 Swift 返回的可选性的已知问题。

    【讨论】:

    • 这很可能是一个编译器错误,但您问题中的代码无效(可能是剪切/粘贴错误?) - var gravity: ForceComputation = { (projectile:Sprite) -> Vector3d in 有一个参数 arity mismatch...
    • 啊,看来你又输入了 ForceComputation
    • ForceComputation 没有第二次使用别名。后面的代码是对原始代码的修改sn-ps。考虑到如果失败的方式,代码不应该编译,或者至少应该有一个警告,因为参数不匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2023-02-04
    • 2012-03-08
    • 2014-10-15
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多