以下3个声明有什么区别?

What is the difference between the following 3 declarations?

var title: UILabel {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}

let title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

lazy var title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

如果我把 'let' 放在第一个,编译器会抱怨 'computed property do not allow let'。好的,有点道理。第一个和第二个之间的唯一区别是“=”和“()”。那么,这是否意味着它不再是计算的 属性?

这是只计算得到的 属性,它会在您每次尝试获取它时计算值:

var title: UILabel {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}

这是常规 属性 由就地调用的闭包(扮演默认值角色)立即初始化的:

let title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

这是惰性的 属性,它只会在首次访问时通过就地调用的闭包进行初始化:

lazy var title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

1.

var title: UILabel {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}

这是一个read only computed property。计算属性不能是 let。这些是使用其他 stored/computed 属性计算的。所以他们没有自己的后备商店。因此,计算属性总是声明为 var.

2.

let title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

这是一个stored property。这被分配了一个 closure 那个 returns 一个 UILabel 对象。该闭包在对象实例化过程中执行,返回的UILabel对象赋值给title.

3.

lazy var title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

是一个lazy stored property。它还分配了一个 returns 一个 UILabel 对象的闭包。但是这个闭包在实例化过程中并没有执行。每当首次使用此 属性 时都会执行它。闭包执行后返回的UILabel对象赋值给title.

除了@PGDev 所说的所有内容,我想指出另一种编写 second/third 声明的方法:

而不是:

let title: UILabel = {
    let label = UILabel()
    textLabel.font = .systemFontOfSize(13)
    return label
}()

你可以这样写:

let title: UILabel = {
    [=11=].font = .systemFontOfSize(13)
    return [=11=]
}(UILabel())

和上面的完全一样,只是代码写的不一样:)