Swift类没有初始值设定项,但是有属性观察者
我刚开始学习swift并对类初始值设定项有疑问。这里是我的示例代码:Swift类没有初始值设定项,但是有属性观察者
struct Resolution {
var width = 0
var height = 0
}
let someResolution = Resolution()
class TV {
var res: Resolution! {
didSet {
res.width = 1
res.height = 1
}
}
}
var television = TV()
var resolution = Resolution()
television.res = resolution
我想使用属性观察者。当我隐式解开属性观察者类型是结构时,一切正常。否则,它说:“类没有初始化。我很困惑,我为什么要暗中提前解开结构。谢谢!
这不完全是从你的问题不清楚,但我相信你会问,为什么你不能替换此:
var res: Resolution! {
...这一点:
var res: Resolution {
您的线索来自全编译器错误消息,您可以通过查看编译器日志(或操场控制台,如果您在操场中)看到:
error: class 'TV' has no initializers
class TV {
^
note: stored property 'res' without initial value prevents synthesized initializers
var res: Resolution {
^
error: 'TV' cannot be constructed because it has no accessible initializers
var television = TV()
当物业的类型为Resolution!
时,你的意思是“它可能为零,但如果有人试图读取它虽然是零,那么这是一个可怕的灾难,我的整个应用程序应该崩溃。”因此,斯威夫特将TV
初始化为res
设为零,并且期望您将其设置为其他值。
然而,当属性的类型为Resolution
,你说,“它不能永远是零,没有过,即使是在没有人看。”这意味着,res
必须已经从一个值TV
被实例化的时刻。但是,这个价值应该是什么?没有默认设置。你有两个选择,如果类型为Resolution
:
-
使用属性初始化它设置一些默认值(这是它看起来就像你正在试图做的):
class TV { var res: Resolution = Resolution(width: 1, height: 1) }
...或与初始化,可以让斯威夫特推断类型:
class TV { var res = Resolution(width: 1, height: 1) }
-
询问谁是创造了
TV
时instan指定初始值tiating类:class TV { init(res: Resolution) { self.res = res } var res: Resolution { didSet { res.width = 1 res.height = 1 } } } var resolution = Resolution() var television = TV(res: resolution)
旁白:这一切使得绝对没有任何意义,因为你改变宽度&高度为1后,立即将分辨率设定(什么?!),但它没有编译。
这样从编译器的“合成初始化器”消息? Swift会为你的类自动创建一个空的init()
,但不会执行任何操作,但如果有任何非可选属性需要初始化,则不会。如果有的话,你必须编写你自己的初始化程序。
(请注意,如果TV
是一个结构,然后斯威夫特将产生init(res:)
对你来说确实与结构,但不带班。)
的第三种选择是使类型Resolution?
:
class TV {
var res: Resolution? {
didSet {
res?.width = 1
res?.height = 1
}
}
}
这是一个更好的选择,而不是Resolution!
,这仅仅是一个等待发生崩溃。隐含的解包选择权应该是最后的手段,可以在非常具体的,仔细考虑的情况下使用。
每个实例变量必须初始化结束时间有一个值。
如果不使用可选的,那么你必须在这里提供一个实际的解决方案实例作为
res
价值 - 和你不这样做,如果你使用一个可选的编译器提供
nil
作为值,因此需要满足一个值。
一种可能性是写你的类是这样的:
类电视{VAR 解析度=分辨率(){ didSet { res.width = 1个 res.height = 1 }} }
现在res
有一个初始值:即实际的Resolution实例。
但是你在做什么是没有错。当您知道在初始化时无法为实例变量提供值时,使用“可选”非常常见,但您打算在后面提供一个值。
读我的书可能会有所帮助:http://www.apeth.com/swiftBook/ch04.html#_initializers – matt
非常感谢!现在我明白了什么是“!”和初始化程序。 – artemchen