【问题标题】:Swift Cannot use instance member within property initializerSwift 不能在属性初始化器中使用实例成员
【发布时间】:2019-06-26 18:50:29
【问题描述】:

我想在课堂上做这样的事情,但 Swift 不允许这样做:

 let minDelay = Float(0.05) //Like #define minDelay 0.05 in Objective-C

 private var delay = minDelay

我收到错误“无法在属性初始化程序中使用实例成员 minDelay”。在不初始化延迟变量 init 或其他什么的情况下纠正此问题的最佳方法是什么?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    Swift 的属性初始化器不能引用其他属性。

    struct S {
        let a = 0
        let b = a // ❌
    }
    

    错误:不能在属性初始化器中使用实例成员a;属性初始化程序在 self 可用之前运行

    这是尝试防止这样的循环定义的一种方法:

    struct S {
        let a = b
        let b = a //❓what would these values even be?
    }
    

    像 Java 这样的一些语言采用更宽容的方法,通过让成员引用它上面的任何成员(即在它上面的一行),形成一个相互关联的成员定义的 directed acyclic graph

    Swift 采取更严格的方法,并彻底禁止它。要解决此问题,您可以:

    1. 将您的 minDelay 变量移动到其他位置。

      • 使其成为静态成员
      • 使其成为不同类型的静态成员(例如 FooConstants 无大小写枚举)。
      • 将其移至全局变量(不要这样做)
    2. 如你所说,设为lazy var

    3. 在初始化程序中设置其值,其中明确表示分配的顺序。

    【讨论】:

      【解决方案2】:

      您可以使用静态变量(这意味着有一个属于该类型的实例):

      class MyClass {
      
          static let minDelay: Float = 0.05
          // You can write `Self.minDelay` starting in Swift 5.1
          private var delay = MyClass.minDelay 
      
      }
      

      有很多方法可以解决这个问题,但这可能是最接近你提到的#define。你也可以完全在类之外定义minDelay,但我认为这没有意义,因为它只与这个类有关。

      【讨论】:

      • Self.minDelay 测试版:)
      • @Sulthan 哦!添加到答案
      • @Sulthan 为什么要将读者与 Self 而不是静态类类型混淆?当类型很重要时应该使用 Self,因为这是一个静态变量(不是类),我看不出有任何理由用静态类型替换 Self
      • @J.Doe 不,没有理由用名称来引用类型。这是关于消除冗余。
      猜你喜欢
      • 2018-01-07
      • 2017-04-04
      • 2021-04-15
      • 2020-06-18
      • 2020-10-24
      • 2021-03-19
      • 2019-12-03
      • 1970-01-01
      相关资源
      最近更新 更多