在Swift中初始化类常量

前端之家收集整理的这篇文章主要介绍了在Swift中初始化类常量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图做这样的事情(这是一个仅用于演示目的的人为例子):

class Test {
  let hello = "hello"
  let world = "world"
  let phrase: String {
    return self.hello + self.world
  }
}

但你不能在Swift中使用let来计算属性.有没有办法在不必编写init()方法的情况下执行此操作?谢谢!

解决方法

let之所以对read-only计算属性不起作用,是因为它用于声明属性的实际值在设置后永远不会改变 – 而不是该属性是只读的.正如 Apple docs所说(强调我的):

You must declare computed properties — including read-only computed@H_404_25@ properties — as variable properties with the var keyword,because their@H_404_25@ value is not fixed. The let keyword is only used for constant@H_404_25@ properties,to indicate that their values cannot be changed once they@H_404_25@ are set as part of instance initialization.

因此,您需要使用var来反映计算属性值随时可能发生变化的事实,因为您在访问它时会动态创建它.虽然在你的代码中,这不可能发生 – 因为你的hello和world属性是自己的常量.但是,Swift无法推断出这一点,所以你仍然需要使用var.

例如:

class Test {
    let hello = "hello"
    let world = "world"
    var phrase: String {
        return self.hello + self.world
    }
}

(这不会改变属性的可读性 – 因为你没有为它提供setter,它仍然是只读的)

但是在您的情况下,您可能需要考虑使用lazy property,因为您的hello和world属性是常量.惰性属性在首次访问时创建,并在其生命周期的剩余时间内保持其值 – 这意味着每次访问它时都不必继续将两个常量连接在一起.

例如:

class Test {
    let hello = "hello"
    let world = "world"
    lazy var phrase: String = {
        return self.hello + self.world
    }()
}

let属性的另一个特征是它们的值应该在初始化之前始终是已知的.因为在此之前可能不知道惰性属性的值,所以还需要将其定义为var.

如果你仍然坚持想要一个let属性,那么据我所知,你有两个选择.

第一个是最好的(尽管你已经说过你不想这样做) – 你可以在初始化器中分配你的短语属性.只要你在super.init调用之前执行此操作,就不必处理选项.例如:

class Test {
    let hello = "hello"
    let world = "world"
    let phrase: String

    init() {
        phrase = hello+world
    }
}

你根本无法内联,因为该范围的self指的是静态类,而不是类的实例.因此,您无法访问实例成员,并且必须使用init()或惰性/计算属性.

第二个选项很糟糕 – 您可以在类级别镜像您的hello和world属性,因此您可以在短语声明中内联访问它们.例如:

class Test {
    static let hello = "hello"
    static let world = "world"

    // for some reason,Swift has trouble inferring the type
    // of the static mirrored versions of these properties
    let hello:String = Test.hello
    let world:String = Test.world

    let phrase = hello+world
}

如果您实际上不需要将hello或world属性作为实例属性,那么您可以将它们设置为静态 – 这将解决您的问题.

猜你在找的Swift相关文章