【问题标题】:"static let" vs "let" for declaring class specific constants用于声明类特定常量的“static let”与“let”
【发布时间】:2020-02-06 07:27:52
【问题描述】:
class CurrencyConverter {

    // 1
    private let conversionRate = 1.3 

    // 2
    private static let conversionRate = 1.3

    func convertToForeign(fromlocal local: Double) -> Double {
        return local * CurrencyConverter.conversionRate
    }
}

let c = CurrencyConverter()
print(c.convertToForeign(fromlocal: 5))

参考上面的代码sn-p,假设我只需要在实例方法中使用常量conversionRate

conversionRate 声明为仅 (1)let 与 (2)static let 的优缺点是什么?

哪种样式更具可读性和优化?

另外,假设我只需要 1 个 CurrencyConverter 的短暂实例,而 conversionRate 本身很庞大(10K 双精度数组)。 (1)let conversionRate 会更优化内存吗?

【问题讨论】:

  • 我个人不会使用static,因为我不用一直写类名。
  • 当你使用 static let 你是说这个值是全局的并且对于你的类的所有实例都是相同的但是当你使用 let 只有你说这个值是恒定的一个实例。现在在您的情况下没有实际区别,因为您使用硬编码值实例化属性,但至少 static 告诉您有关属性用途的一些信息。

标签: swift static compile-time-constant


【解决方案1】:

两者都不是。使用一个无人居住的(无大小写)enum 创建一个Constant 命名空间;读起来更好。

class CurrencyConverter {
    private enum Constant {
        static let conversionRate = 1.3
    }
    func convertToForeign(fromlocal local: Double) -> Double {
        return local * Constant.conversionRate
    }
}

let c = CurrencyConverter()
print(c.convertToForeign(fromlocal: 5))

【讨论】:

  • 我喜欢这种风格。但是,假设我只需要 1 个此类的短暂实例,并且 conversionRate 本身很庞大。 “let conversionRate”会更优化内存吗?
  • @Raunak 我会将您的conversionRate 声明为扩展Double extension Double { static let conversionRate = 1.3 } 的静态属性,这样您就可以做到local * .conversionRate
  • @Raunak 编译器通常会加载。将所有常量原语重复数据删除到符号表中,因此 1.3 无论如何都在内存中;它不像当你要求它时它从磁盘加载它。所以不管它是一个实例还是静态常量——它们编译成同样的东西,如果这是一个像 UIImage 这样的类,那就不是真的,因为这样数据实际上是从磁盘加载的,
【解决方案2】:

在下面的代码中,

private let conversionRate = 1.3

上面是一个实例变量,即只要CurrencyConverterc)的实例存在,它就会持续存在。一旦c 超出范围,conversionRate's 范围也会结束。

然而,在下面的代码中

private static let conversionRate = 1.3

这里conversionRateclass CurrencyConverter 相关联,而不是实例。因此,即使实例 c 超出范围,即只要应用程序运行,它也会保留在内存中。

因此,创建实例变量比创建静态变量更优化。

【讨论】:

    【解决方案3】:

    如果您将static 添加到class methodfield,则它被称为class field/method,这样您就可以在不创建instanceclass 的情况下访问它。

    如果没有 static 关键字,field/method 将是 instance field/method,这只能通过创建类的实例来访问。

    在这种情况下,最好使用 static 字段,因为它不依赖于其他类 fields/methods,如果您有许多相同类的对象,它也可以节省内存。

    【讨论】:

    • 我的问题清楚地说:“假设我只需要在实例方法中使用常量conversionRate”
    • 如果你知道静态和非静态的区别,那么是静态还是非静态就很清楚了。
    • 而且还取决于你为这个类创建了多少个对象。
    猜你喜欢
    • 1970-01-01
    • 2018-09-18
    • 2018-05-28
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 2020-12-17
    相关资源
    最近更新 更多