Mar*_*n R 102
结构和枚举都有效.作为一个例子,两者
struct PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
Run Code Online (Sandbox Code Playgroud)
和
enum PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
Run Code Online (Sandbox Code Playgroud)
工作并定义静态属性PhysicalConstants.speedOfLight.
这两个struct和enum是值类型,以便将适用于枚举为好.但这与此无关,因为您根本不必创建值:静态属性(也称为类型属性)是类型本身的属性,而不是该类型的实例.
如链接文章中所述:
使用无大小写枚举的优点是它不会被意外地实例化并且作为纯命名空间工作.
所以对于一个结构,
let foo = PhysicalConstants()
Run Code Online (Sandbox Code Playgroud)
创建一个(无用的)类型的值PhysicalConstants,但是对于无大小写的枚举,它无法编译:
let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers
Run Code Online (Sandbox Code Playgroud)
jgl*_*sse 14
这是一个简短的回答:你的常数需要是独一无二的吗?然后使用枚举,强制执行此操作.
想要使用几个不同的常量来包含相同的值(通常用于清晰度)?然后使用一个允许这个的结构.
Sil*_*ntK 10
两者之间的一个区别是结构可以被实例化,而枚举则不能。因此,在您只需要使用常量的大多数情况下,最好使用枚举以避免混淆。
例如:
struct Constants {
static let someValue = "someValue"
}
let _ = Constants()
Run Code Online (Sandbox Code Playgroud)
上面的代码仍然有效。
如果我们使用枚举:
enum Constants {
static let someValue = "someValue"
}
let _ = Constants() // error
Run Code Online (Sandbox Code Playgroud)
上面的代码将是无效的,因此避免混淆。
在Combine框架中,Apple 选择优先使用枚举作为命名空间。
Run Code Online (Sandbox Code Playgroud)enum Publishers作为发布者的类型的命名空间。
Run Code Online (Sandbox Code Playgroud)enum Subscribers用作订阅者的类型的命名空间。
Run Code Online (Sandbox Code Playgroud)enum Subscriptions与订阅相关的符号的命名空间。
尽管我同意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")
}
Run Code Online (Sandbox Code Playgroud)
使用一个结构,它将匹配并打印出来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")
}
Run Code Online (Sandbox Code Playgroud)
您会注意到,在该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")
}
Run Code Online (Sandbox Code Playgroud)
注意case语句中需要括号,因为它现在是一个函数。
不利的一面是,既然我们已经使其成为一个函数,则每次调用它都会执行一次。因此,如果它只是一个简单的原始类型(例如String或)Int,那么还算不错。它本质上是一个计算属性。如果它是一个需要计算的常数,而您只想计算一次,请考虑将其计算为其他属性,然后在闭包中返回该已计算的值。
您还可以使用专用的初始化器覆盖默认的初始化器,然后获得与无case枚举相同的编译时错误优度。
struct StaticVars {
static let someString = "someString"
private init() {}
}
Run Code Online (Sandbox Code Playgroud)
但是与此相关的是,您希望将结构的声明放入其自己的文件中,因为如果将其声明为与View Controller类的文件相同,则该类的文件仍然能够意外地实例化一个无用的文件。的实例StaticVars,但在类文件的外部,它将按预期工作。但这是你的电话。
| 归档时间: |
|
| 查看次数: |
21143 次 |
| 最近记录: |