为什么整个模块优化无法推断出同一模块中公共的非覆盖模块类/方法的最终结果?

时间:2019-05-28 11:43:27

标签: swift whole-module-optimization

this article中,我引用以下句子:

  

使用整体模块优化来推断内部声明的最终结果。   具有内部访问权限的声明(如果未声明任何内容,则为默认值)   仅在声明它们的模块内可见。因为   Swift通常会分别编译组成模块的文件,   编译器无法确定内部声明   在另一个文件中被覆盖。但是,如果整个模块   启用了优化,所有模块都在一起编译   同时。这使编译器可以对   整个模块在一起,并使用内部方法推断final声明   如果没有可见的替代。        让我们回到原始代码段,这一次为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)
}
  

使用“全模块优化”功能编译该代码段时,   编译器可以推断final的属性点,速度和   方法调用updatePoint()。相反,不能推断出   由于update()具有公共访问权限,因此update()是最终的

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

1 个答案:

答案 0 :(得分:1)

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