我想知道:在Swift中声明一个非有序的标量值列表的最佳方法是什么,它完全由符号支持并且易于被编译器检查?
我想说我想要声明一个LetterSpacing
值列表,我希望通过符号在我的代码中访问和使用这些值。
我的理解是我应该像这样声明一个快速的enum
:
enum LetterSpacing: Double {
case Short = 1.0
case Medium = 2.0
case Large = 3.0
}
这样可以正常工作并获得编译器检查,但令人讨厌的部分是每次我需要LetterSpacing.XXX.rawValue
来访问基础值。 .rawValue
让我感到困扰,不得不在任何地方指定它。
我认为用struct
等声明static let Short = 1.0
是不合理或不合适的。
那么,你会如何处理这类案件?是否有可能在现有类型中添加一些协议/扩展swift魔法,以便能够将Short
枚举作为自己的值? (即let size = LetterSpacing.Short
的类型为Double
,其值为1.0
)
答案 0 :(得分:6)
由于多种原因,enum
会首选。
首先,enum
实际上最终会占用更少的内存。这是因为Swift将enum
值优化为单个字节(无论原始值是什么),当我们在rawValue
上调用enum
时,我们只能从中获取完整值值。将以下代码粘贴到游乐场中以查看:
struct LetterSpacingS {
static let Short: Double = 1.0
}
enum LetterSpacingE: Double {
case Short = 1.0
}
sizeofValue(LetterSpacingS.Short)
sizeofValue(LetterSpacingE.Short)
double
是8个字节,而enum
只是1。
其次,第一点的重要性不仅限于内存占用。它也可以应用于我们程序的执行效率。如果我们想比较结构中的两个值,我们将比较8个字节。如果我们想比较两个枚举值,我们只比较一个字节。在这种特定情况下,我们有1/8的字节要比较。这只是一个双倍。考虑到Swift枚举也可以将字符串作为支持类型。比较两个字符串可能会非常昂贵,只需比较它们隐藏在enum
后面的单个字节。
第三,使用枚举,一般来说,我们不会比较你真正不想做的浮点数。
第四,使用枚举为我们提供了一些类型安全性,我们无法使用常量结构。常量的所有结构都是让我们定义一些预定义的常量来使用。
struct LetterSpacingS {
static let Short = 1.0
static let Medium = 2.0
static let Long = 3.0
}
但是现在一个方法看起来会期望其中一个值吗?
func setLetterSpacing(spacing: Double) {
// do stuff
}
现在当Joe-Coder进来时会发生什么:
foo.setLetterSpacing(-27.861)
没有什么能阻止他。它需要一个双倍,任何双倍。这可能不是那么常见,但是如果这是在你正在分发的库中,那么你就会对这些问题和评论持开放态度,例如“当我传入5.0的值时,它看起来根本不正确!”< / p>
但请与使用enum
进行比较。
func setLetterSpacing(spacing: LetterSpacing) {
// do stuff
}
现在,我们只获得了三个预定义的选择,以便传入这个论点。
除了enum
所持有的值的内部使用之外,您还必须使用rawValue
太多。
第五个原因并不是在结构上使用枚举的强有力的理由,但主要是为了消除在枚举上使用结构的建议的原因之一。 Swift枚举可以嵌套在其他类型中,其他类型可以嵌套在Swift枚举中。您不必使用结构来获取嵌套类型。
答案 1 :(得分:2)
我不明白为什么用三个静态常量创建一个Struct是不合适的。我看到很多Swift代码(也来自Apple)都是这样做的。
Structs可以让你创建好的层次结构:
struct Style {
struct Colors {
static let backgroundColor = UIColor.blackColor()
...
}
struct LetterSpacing {
static let Short = 1.0
}
...
}