在swift中表示枚举成员值?

时间:2017-07-28 19:47:33

标签: swift enums

enum CompassPoint {
case north, east, south, west
}

var compassHeading = CompassPoint.west

我读过“枚举的案例值是实际值,而不仅仅是编写原始值的另一种方式。”我对这个说法感到困惑。如果案例本身是新类型,则不应将其初始化为:

var compassHeading = CompassPoint.west()

根据apple的说法,枚举不包含隐式初始化器......这让我更加困惑。

2 个答案:

答案 0 :(得分:1)

TLDR;

如果输入 case enum case已关联的值,那么类型此{ {1}}将是一个高阶函数,其参数匹配关联的值,并返回与case本身匹配的类型。由于允许不同的案例具有不同类型(和数量)的关联值,因此键入的enum enum类型可能会有所不同。这里的重要性是case 实例(始终具有给定enum )和显式类型<之间的差异/ em>案例本身(当不是值时)。

case 实例始终与enum相关联,并始终拥有case 类型 >

我不知道您的报价来源,但the Language Guide在将每个enum描述为值时非常简单:

  

枚举定义了一组相关值和的一个公共类型   使您能够以类型安全的方式使用这些值   代码。

具有不同关联值的case:s的类型案例将定义不同类型的高阶函数类型,所有类型都返回enum的类型

但是除了enum的{​​{1}} 实例的价值观之外,可能会注意到每个case(输出!)本身有一个类型(虽然不是enum意义上的&#34;新&#34;类型,但在同一case的不同情况之间可能会有所不同。如果案例没有关联值,则此类型仅等于struct Foo {}本身,但如果enum使用关联值,则{{1> enum将是一个更高阶的函数类型,其参数类型为关联值,返回类型为case类型本身。由于不同的案例可以有不同的关联值,因此不同的案例可以对应不同的类型。

  

或者,枚举情况可以指定any的关联值   类型与每个不同的案例值一起存储,就像联合一样   或变体用其他语言做。您可以定义一组通用的   相关案例作为一个枚举的一部分,每个案例都有一个   与之相关的适当类型的不同值集。

     

...

     

您可以定义Swift枚举来存储关联的值   任何给定的类型,和值类型可以是不同的每种情况   如果需要,枚举

case

现在,由于不同的案例有不同的类型(当输入时,而不是enum实例的一部分),&#34;初始化&#34;给定enum Foo { case bar case baz(Int) // Int associated value case bax() // Void associated value } print(type(of: Foo.bar)) // Foo print(type(of: Foo.baz)) // (Int) -> Foo print(type(of: Foo.bax)) // () -> Foo func foo(_ closure: (Int) -> Foo) -> Foo { return closure(42) } let foobaz = foo(Foo.baz) // 'foobar' is 'Foo.baz' (ass. value 42) let foobar = foo(Foo.bar) // wont compile, type mismatch let foobax = foo(Foo.bax) // wont compile, type mismatch 实例的给定Foo看起来会有所不同,具体取决于case是否具有任何关联值。

enum

如您所见,只需输入case类型和案例(因为此案例的类型将会实例化),实例化一个没有关联值的enum Foo { case bar case baz(Int) // Int associated value case bax() // Void associated value } var foo = Foo.bar // no associated values foo = Foo.baz(42) // expects Int associated value: needs to be _invoked_(/called) foo = Foo.bax() // expects empty tuple '()' associated value: needs to be _invoked_(/called) 实例case本身:与enum比较),而实例化时需要调用具有关联值(甚至enum)的案例。这个调用,特别是对于上面的Foo.bar情况,可能看起来很像一些隐式初始化,但它只是调用闭包类型来接收返回类型{{1的实例 }}

()

答案 1 :(得分:0)

  

如果案例本身就是新类型,则不应将其初始化为:

var compassHeading = CompassPoint.west()

这只是一个符号问题。但我认为你可以这样对自己证明这一点。

可以添加一个你想要的那种初始化器,但是你初始化的是CompassWest,而不是特定的情况:

enum CompassPoint {
    case west
    init() {
        self = .west
    }
}

let cp = CompassPoint()

此外,如果CompassPoint的west案例具有相关值,那么您所要求的只是您 所说的那样:

enum CompassPoint {
    case west(Int)
}
let cp = CompassPoint.west(25)

但由于没有案例具有关联值,因此所有CompassPoint.west个对象实际上都是同一个对象。没有维持状态 - 记住,枚举没有存储的属性。所以这不像实例化结构或类。 CompassPoint.west不是这个CompassPoint案例的实例化; 只有CompassPoint.west在宇宙中。

(从这个意义上讲,case .west更像是一个struct的静态属性而不是类的实例。所以引用它的符号就像引用一个静态的符号一样结构的属性。)