我不确定两者中哪个最好定义常量。结构或枚举。每次我使用与否,都会复制一个结构吗?当我想到带有static let
常量的结构时,我认为它会一直复制是没有意义的。但是,如果它不会被复制,那我拿走什么都没关系?
选择结构或枚举有什么优势?
我不确定两者中哪个最好定义常量。结构或枚举。每次我使用与否,都会复制一个结构吗?当我想到带有static let
常量的结构时,我认为它会一直复制是没有意义的。但是,如果它不会被复制,那我拿走什么都没关系?
选择结构或枚举有什么优势?
Answers:
结构和枚举均起作用。例如,两者
struct PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
和
enum PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
工作并定义静态属性PhysicalConstants.speedOfLight
。
这两个struct
和enum
是值类型,以便将适用于枚举为好。但这无关紧要,因为您根本不必创建值:静态属性(也称为类型属性)是类型本身的属性,而不是该类型的实例。
如链接文章所述:
使用不区分大小写的枚举的优点是它不会被意外实例化并且可以用作纯名称空间。
所以对于一个结构,
let foo = PhysicalConstants()
创建一个type的(无用)值PhysicalConstants
,但是对于一个不区分大小写的枚举,它将无法编译:
let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers
private init() {}
到Struct
示例中,它还将具有无法即时实例化的“优势”。(自然地,某些开发人员可以通过在:的扩展中包括一个初始化程序来规避此“优势”,Struct
但是如果出于某种原因,我们更愿意以Struct
“纯名称空间”的方式使用a ,而不是使用enum
,那么私有初始化程序可能是一个很好的实例,不要用作实例保护措施)。
struct Constants static let speedOfLight = 300
与enum Constants enum Light : Int case speed = 300
进行比较的。您也可以比较一下答案中的内容吗?还是该比较有另一个答案?
虽然我同意Martin R的观点,但Ray Wenderlich样式指南指出,由于枚举是纯名称空间,因此在几乎所有用例中枚举都更好,这是一个好地方,但在某个地方使用struct
王牌enums
。
让我们从struct版本开始:
struct StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
使用结构,它将匹配并打印出 Matched StaticVars.someString
。
现在,让我们考虑无大小写的枚举版本(只需将关键字更改struct
为enum
):
enum StaticVars {
static let someString = "someString"
}
switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
您会注意到,case StaticVars.someString:
在线的switch语句中出现编译时错误。错误是Enum case 'someString' not found in type 'String'
。
通过将static属性转换为返回类型的闭包,可以找到一种伪解决方法。
因此,您可以这样更改它:
enum StaticVars {
static let someString = { return "someString" }
}
switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}
注意case语句中需要括号,因为它现在是一个函数。
不利的一面是,既然我们已经使它成为一个函数,则每次调用它都会被执行。因此,如果它只是一个简单的原始类型,例如String
或Int
,那么还不错。它本质上是一个计算属性。如果它是一个需要计算的常数,而您只想计算一次,请考虑将其计算为其他属性,然后在闭包中返回该已计算的值。
您还可以使用专用的初始化器覆盖默认的初始化器,然后获得与无case枚举相同的编译时错误优度。
struct StaticVars {
static let someString = "someString"
private init() {}
}
但是,与此相关的是,您希望将结构的声明放入其自己的文件中,因为如果您将其声明与一个View Controller类放在同一文件中,则该类的文件仍然能够意外地实例化一个无用的文件。的实例StaticVars
,但在类文件的外部,它将按预期工作。但这是你的电话。