Swift 不能在属性初始化器中使用实例成员

Posted

技术标签:

【中文标题】Swift 不能在属性初始化器中使用实例成员【英文标题】:Swift Cannot use instance member within property initializer 【发布时间】: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 或其他什么的情况下纠正此问题的最佳方法是什么?

【问题讨论】:

【参考方案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 采取更严格的方法,并彻底禁止它。要解决此问题,您可以:

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

    使其成为静态成员 使其成为不同类型的静态成员(例如 FooConstants 无大小写枚举)。 将其移至全局变量(不要这样做)

    如你所说,设为lazy var

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

【讨论】:

【参考方案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 不,没有理由用名称来引用类型。这是关于消除冗余。

以上是关于Swift 不能在属性初始化器中使用实例成员的主要内容,如果未能解决你的问题,请参考以下文章

不能在属性初始化器中使用实例成员“pdfName”;属性初始化程序在“自我”可用之前运行

结构中的 Swift/SwiftUI 属性初始化程序错误

无法在属性初始化程序中使用实例成员,将变量设置为惰性不起作用

如何快速初始化我的数组

不能在属性初始值设定项中使用实例成员 '';属性初始化程序在 'self' 可用之前运行

错误不能在属性初始化程序中使用实例成员“xxx”