"static let"与"let"用于声明类特定常量的区别

3
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))

参考上面的代码片段,假设我需要在实例方法中仅使用常量conversionRate

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

哪种风格更易读且更优化?

此外,假设我只需要一个短暂存在的CurrencyConverter实例,并且conversionRate本身庞大(一个包含10K个 Double 的数组)。 那么,(1)let conversionRate是否更加内存优化?


个人而言,我不会仅仅因为不用一直写类名就使用 static - Sweeper
2
当你使用 static let 时,你在表明这个值是全局的,并且对于类的所有实例都是相同的,但是当你只使用 let 时,你在表明这个值对于一个实例来说是常量。现在在你的情况下,由于你用硬编码的值实例化了属性,所以没有实际区别,但至少 static 告诉你一些关于属性目的的信息。 - Joakim Danielson
请参阅Swift常量:结构体或枚举 - Martin R
3个回答

2
不需要。使用一个无人居住的(大小写不敏感的)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))

我喜欢这种风格。但是假设我只需要一个短暂的类实例,并且conversionRate本身很笨重。那么使用"let conversionRate"会更加内存优化吗? - Raunak
@Raunak 我会将你的 conversionRate 声明为扩展 Double 的静态属性 extension Double { static let conversionRate = 1.3 } 这样你就可以使用 local * .conversionRate - Leo Dabus
1
@Raunak 编译器会将所有常量原语加载到符号表中,并进行去重,因此无论如何,1.3都在内存中;它不会在您请求时从磁盘加载。因此,它是实例常量还是静态常量并不重要——它们编译成相同的内容。但如果这是像UIImage这样的类,那么数据实际上确实会从磁盘加载。 - Josh Homann

2
在下面的代码中,
private let conversionRate = 1.3

上面是一个实例变量,也就是说只要 CurrencyConverter (c) 的实例存在,它就会持续存在。一旦 c 超出范围,conversionRate's 的作用域也会结束。
而在下面的代码中:
private static let conversionRate = 1.3

在这里,conversionRateclass CurrencyConverter 相关联,而不是与 instance 相关联。因此,即使实例 c 超出范围,即只要应用程序运行,它就会保留在内存中。
因此,创建实例变量比创建静态变量更为优化。

0
如果你在类的方法或字段上添加 static 关键字,那么它就被称为类字段/方法,这样你就可以在不创建类实例的情况下访问它。
如果没有 static 关键字,该字段/方法将是实例字段/方法,只能通过创建类的实例来访问。
在这种情况下,最好使用静态字段,因为它不依赖于其他类字段/方法,而且如果你有许多相同类的对象,它也很节省内存。

1
我的问题清楚地说明:“假设我只需要在实例方法中使用常量conversionRate”。 - Raunak
如果你知道静态和非静态之间的区别,那么就清楚是选择静态还是非静态了。 - Sohail Ashraf
还取决于您创建了多少个该类的对象。 - Sohail Ashraf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接