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”;属性初始化程序在“自我”可用之前运行
无法在属性初始化程序中使用实例成员,将变量设置为惰性不起作用