swift 枚举中关联值和原始值之间的差异

Difference between associated and raw values in swift enumerations

Swift 枚举具有关联值和原始值。但是我不清楚这些值的用例。因此,如果有人能解释关联值和原始值之间的区别,我将不胜感激,举个例子会很有帮助。

原始值适用于枚举中的每个案例都由编译时设置值表示的情况。它们类似于常量,即

let A = 0
let B = 1

类似于:

enum E: Int {
    case A  // if you don't specify, IntegerLiteralConvertible-based enums start at 0
    case B
}

因此,A 在编译时设置了 0B1 等的固定原始值。它们都必须是相同的类型(原始值的类型是针对整个枚举的,而不是每个单独的案例)。它们只能是文字可转换的字符串、字符或数字。而且它们都必须是 distinct(没有两个枚举可以具有相同的原始值)。

关联值更像是变量,关联一个枚举案例:

enum E {
    case A(Int)
    case B
    case C(String)
}

这里,A 现在有一个关联的 Int,可以保存 任何 整数值。另一方面,B 没有关联值。 C 有关联的 String。关联类型可以是任何类型,而不仅仅是字符串或数字。

类型 E 的任何给定值只会包含一种关联类型,即如果枚举是 A,则 IntString 如果枚举是 C。它只需要足够的 space 来满足两者中较大的一个。像这样的类型有时被称为 "discriminated unions" – 联合是一个可以包含多种不同类型的变量,但你知道(从枚举的情况)它包含的是哪一个。

它们甚至可以是通用的。其中最常见的例子是Optional,它的定义是这样的:

enum Optional<T> {
    case .Some(T)
    case .None
}

Swift 枚举原始值与关联值

EnumerationsEnum 允许您创建一组有限的值和枚举变量引用来自集合

单个值]

在Swift中,枚举不能同时具有原始值关联值

原始值

enum Color: String {
    case white = "#ffffff"
    case black = "#000000"
}

“原始值”是一种类型的唯一标识符。这意味着您可以通过 ID 构造您的类型。例如:

XCTAssertEqual(Color.white, Color(rawValue: "#ffffff"))

获取原始值使用

Color.white.rawValue

关联值

enum Color {
    case white
    case black
    
    case custom(hex: String)
}

Swift 的“关联值”允许您将附加信息添加到可以动态定义的枚举中。请注意,当我们引入“关联值”时,我们会省略“原始值”并添加类型注释。这使得无法使用“原始值”来重建您的类型,因为它现在是动态设置的。

您可以阅读“关联值”如下:

let myColor = Color.custom(hex: "#ff00ff")
    
switch myColor {
case .custom(let hex):
    print("custom color hex:\(hex)") //#ff00ff
case .white:
    print("white color")
case .black:
    print("black color")
}

Associated Value 枚举的好例子是 Result[About]

请注意Objective-C不支持Swift的枚举(Int-bound除外)

也去坎帕雷

原始枚举

if case .error = someResult {
    //some logic
}

关联枚举

if case .success(let result) = someResult, result == "ok" {
    //some logic
}

@Airspeed Velocity 和@yoAlex5 的回答很好地解释了差异,但他们指出

enums can have either associated either raw values.

Swift4 和 5 并非如此。 Here 很好地说明了将它们都放在一个枚举中。当然,您需要原始值初始化程序的默认值。