【问题标题】:Why can't Whole Module Optimalization infer final on public non-overridden module classes/methods in the same module?为什么整个模块优化不能推断同一模块中公共非覆盖模块类/方法的最终结果?
【发布时间】:2019-05-28 11:43:27
【问题描述】:

来自this article,我引用下面这句话:

使用整体模块优化来推断内部声明的最终结果。 具有内部访问权限的声明(如果未声明任何内容,则为默认值) 仅在声明它们的模块中可见。因为 Swift 通常会分别编译组成模块的文件, 编译器无法确定内部声明是否 在不同的文件中被覆盖。但是,如果整个模块 启用优化,所有模块在 同时。这允许编译器对 将整个模块放在一起并推断最终声明与内部 如果没有可见的覆盖。 让我们回到原来的代码 sn-p,这次给 ParticleModel 添加了一些额外的公共关键字。

public class ParticleModel {
    var point = ( x: 0.0, y: 0.0 )
    var velocity = 100.0

    func updatePoint(newPoint: (Double, Double), newVelocity: Double) {
        point = newPoint
        velocity = newVelocity
    }

    public func update(newP: (Double, Double), newV: Double) {
        updatePoint(newP, newVelocity: newV)
    }
}

var p = ParticleModel()
for i in stride(from: 0.0, through: times, by: 1.0) {
    p.update((i * sin(i), i), newV:i*1000)
}

当使用整体模块优化编译这个 sn-p 时 编译器可以根据属性 point、velocity 和 方法调用 updatePoint()。相比之下,不能推断出 update() 是最终的,因为 update() 具有公共访问权限

如果 ParticalModel 没有在当前模块中被覆盖,为什么 WMO 不能静态调度对 update() 的调用?不允许在其他模块中覆盖ParicleModel(因为它的访问修饰符是public,而不是open)。我希望类中的每个方法和属性都可以推断出final,因为它没有在当前模块中被覆盖,但是文档明确提到它不能推断出final

【问题讨论】:

  • 请注意,链接的文章早于open 访问级别的引入,因此public 的语义与现在的open 具有相同的语义。你是对的,如果在模块中没有覆盖对 public 成员的调用,现在应该使用 WMO 静态调度它。
  • @Hamish 哦,这听起来合乎逻辑。这也是一个很好的答案:)
  • 我来这里是为了问同样的问题。谢谢!

标签: swift


【解决方案1】:

链接的文章是为 Swift 2 编写的,它早于 Swift 3 (SE-0117) 中引入 open 访问级别。因此,它所指的public 现在在语义上就是open 访问级别。你确实是正确的,如果编译器可以证明它没有在同一个模块中被覆盖,那么现在将静态分派对 public 成员的调用并启用整个模块优化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 2015-03-28
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2023-03-04
    相关资源
    最近更新 更多