【问题标题】:Does directly calling a Swift enum instance method create an instance?直接调用 Swift 枚举实例方法会创建实例吗?
【发布时间】:2015-09-08 15:45:21
【问题描述】:

假设我有一个枚举,例如:

enum AnimalType {
    case Dog
    case Cat

    func barks() -> Bool {
        switch self {
        case Dog:
            return true
        case Cat:
            return false
        }
    }
}

如果我这样做的话:

func pickAnimal(shouldBark: Bool) {

    switch shouldBark {

    case AnimalType.Dog.barks():
        println("you should pick dogs")

    case AnimalType.Cat.barks():
        println("you should pick cats")

    default:
        println("don't pick cats or dogs")
    }
}

调用AnimalType.Dog.barks()AnimalType.Cat.barks() 是否实例化AnimalType

【问题讨论】:

  • bark 打电话给shouldBark 还是打错字了?
  • @luk2302 感谢您指出这一点,我更正了。

标签: ios macos swift enums


【解决方案1】:

是的,在这些示例中,AnimalType.Dog.barks() 实例化了一个 AnimalType

毕竟barks()是一个实例方法。它不能被实例调用。

实例的生命周期将非常短。只要足够长的时间调用barks() 方法,就是这样。

【讨论】:

  • 逻辑上是的。但从编译的汇编代码的检查来看,AnimalType.Dog.barks() 似乎是在编译时评估的(至少在优化模式下)。
【解决方案2】:

我整理了一个小型测试项目并通过 Instruments 运行它,我的发现反映了 @martin-r 的发现。虽然创建枚举的新实例是有道理的,但似乎在编译时已对其进行了优化。

在此屏幕截图中,您可以看到该方法中执行的唯一分配来自首次使用 println():

【讨论】:

  • 有趣。但是,运行时如何在不实例化枚举的情况下评估 switch 子句呢?
  • 但是枚举是值类型,对于像这样没有关联值的东西,它应该只是一个普通整数,无论​​如何都不应该有任何“分配”。
【解决方案3】:

“实例化AnimalType”是什么意思?

值类型(如 struct 或 enum)上的实例方法在编译时解析,因此它相当于调用一个静态函数,该函数将接收者作为参数称为 self。 (变异方法相当于inoutself 参数;像bark 这样的非变异方法相当于普通的self 参数。)所以你的问题基本上相当于问:“是否评估@ 987654327@(如果有一个函数barks 使用AnimalType)实例化一个AnimalType

AnimalType 是一个枚举,其 case 没有关联值。所以基本上它相当于一个整数(除了类型安全)。所以你的问题相当于问:“评估barks(42)(如果有一个函数barks采用Int)是否实例化Int

看看这是一个多么愚蠢的问题?我的意思是,在某种意义上,函数内部会有一个参数,而那个参数的类型是Int。如果这是一个按值参数,那么我猜根据定义Int 的新副本存在于该函数的范围内,因此Int“被实例化”。虽然编译器可能会内联函数并优化参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-09
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多