需要澄清Swift中的枚举类型

时间:2015-08-24 00:05:37

标签: swift enums

我试图了解Swift中的Enumerations,但我对变量的赋值感到困惑。这是一个例子:

enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

var myPlanet = Planet.Mercury 

我对最后一行感到困惑。是否为 myPlanet 变量分配了一个 Planet 对象,其中 Mercury 为其值?

3 个答案:

答案 0 :(得分:4)

它不是一个真正的星球"对象"因为Swift更喜欢术语" Type"。一个"对象"意味着它是一个"类的实例。"课程,枚举和Swift中的结构比其他语言略微模糊了一些线条。

Planet不是一个类,而是一个枚举 - 一组相关的"成员值"。你真的在计算或者计算"小组中的所有各种选项,并说出每个选项的名称。这为每个值提供了一个有用的别名,允许您按名称引用行星,而不是说#34;行星#1,#2,#3,#4,#5 ..."

任何你有相同选项的有限集合的情况都可能是一个很好的候选者:"北,南,东,西"是另一个常见的例子。

您在此处执行的操作是声明新变量myPlanet,并将其初始值分配给Planet枚举成员值MercuryPlanet类型未显式声明,但是从上下文推断 - 此新变量必须属于Planet类型,以便保持所需的.Mercury

另一种声明是:var myPlanet: Planet = .Mercury 通过显式声明var的类型为Planet,您可以从右侧省略Planet

此外,因为它是var&不是let您以后可以将myPlanet更改为任何"成员值"行星枚举。由于myPlanet只能是可能的Planet选项中的一个,因此您只需要引用成员值:

myPlanet = .Earth

但是,您无法将myPlanet更改为其他类型(无论是枚举,结构还是类),因为其类型已定义为Planet

有关更多示例/详细信息,请参阅Swift Programming Language Guide的枚举章节(尽管此示例相同,因此您可能正在阅读它。)

基于评论的编辑:

  

对我而言Planet.Mercury意味着一种名为Planet的枚举类型,其中只有一个Mercury案例。

您的myPlanet 变量属于Type Planet,只分配了 .Mercury。 " Planet.Mercury"作为一个声明就像指向行星的菜单,价值:水星。"

基本枚举是一个可能的选项列表,如菜单:

List of Planets to Choose From
1. Mercury
2. Venus
3. Earth
4. etc... 

变量myPlanet是一个一次只能有1个值的容器。 由于您将其设置为Planet枚举定义中列出的选项中的一个,因此Swift推断它必须是Planet类型。从那时起,这个容器被标记为"仅用于行星"并且其指定值只能来自枚举列表。 Planet枚举本身是静态的 - 它是餐厅菜单,并且始终包含相同的选项(除非您编辑枚举定义本身)。

  

如果我用一个名为Planet的类来编写它,我将其视为myPlanet = Planet(名称:" Mercury")。你有一个类比可以帮助我掌握枚举概念吗? - 沃尔特

使用类示例,您将使用方法初始化Planet实例,并将属性name设置为String" Mercury"。这在许多方面有所不同。一个,"名称"在这种情况下是Type String的属性,它具有getter / setter方法等。您可以将name设置为您想要的任何内容:Planet.name = "Walter"您还必须按名称访问该属性,并且为它提供一个价值。枚举不是这样。

使用枚举,您拥有的只是预定义的可能选项列表。 水星,金星,地球,火星等。枚举"会员价值"只是昵称,类似于"条目#1,条目#2,条目#3和#34;的别名。如果" Planet.Walter"如果不在预定义列表中,则无法将Type Planet的变量分配给该值。它知道它必须是Planet,但它不会在选项中找到case Walter

  

另外,我仍然感到困惑的原因与访问枚举中的计算属性有关。例如,如果我有一个名为size的计算属性,该属性基于枚举中的self,则访问的方式是myPlanet.size。这意味着它等同于Planet.Mercury.size。如何通过案例>值Mercury访问计算属性?

计算属性是Swift模糊传统面向对象编程线的地方之一,因为它们存在于类,枚举和结构中,因此可能会让人感到困惑。

myPlanet.size并不一定等于Planet.Mercury.size - 它可能是Planet.size,其中size是从枚举本身内的函数返回的计算属性。 请参阅此问题以获取示例: Swift Tour Card.createDeck() Returning [{(enum value), (enum value)}]

以下是卡片组示例中未经测试的变体:

enum Planet {
    case Mercury, Venus, Earth, Mars

    func size() -> String {
       switch self {
          case .Mercury:
            return "pretty darn small!"
          case .Venus:
            return "still small!"
          case .Earth:
            return "we think this is normal"
          case .Mars:
            return "slightly bigger than Earth"
      }
    }

}

var myPlanet: Planet = .Mercury
print(\myPlanet.size()) //"pretty darn small!"
myPlanet = .Mars
print(\myPlanet.size()) //"slightly bigger than Earth"

采用这种方法,"尺寸" function是Planet枚举的方法,类似于对象如何具有实例方法,或者struct也可以具有方法。在分配值之后调用myPlanet.size()就像是说'#34;我是类型星球,所以如果我看着自己,我知道我是水星,所以当我执行这个方法时,我有因为我是星球,我回归水星的价值。"更改指定的值,方法保持不变,但返回的值现在不同,因为myPlanet现在具有不同的值。

答案 1 :(得分:1)

我不会说这是您分配给myPlanet对象。您正在为myPlanet分配Mercury,这是枚举 Planet成员Apple's documentation州:

  

如果您熟悉C,您将知道C枚举将相关名称分配给一组整数值。 Swift中的枚举更加灵活,并且不必为枚举的每个成员提供值。如果为每个枚举成员提供了一个值(称为“原始”值),则该值可以是字符串,字符或任何整数或浮点类型的值。

他们继续详细说明(在我看来,回答你的问题):

  

枚举中定义的值(例如NorthSouthEastWest)是该枚举的成员值(或成员)。 case关键字表示即将定义新的成员值行。

     
    

请注意

         

与C和Objective-C不同,Swift枚举成员在创建时未分配默认整数值。在上面的CompassPoint示例中,NorthSouthEastWest并非隐含地等于01,{ {1}}和2。相反,不同的枚举成员本身就是完全成熟的值,具有明确定义的3类型。

  

将对象指定为值时,您并不完全错误 - 正如documentation continues所示:

  

Swift中的枚举本身就是一流的类型。它们采用传统上仅由类支持的许多功能,例如计算属性以提供有关枚举当前值的其他信息,以及实例方法以提供与枚举所代表的值相关的功能。枚举还可以定义初始值设定项以提供初始成员值;可以扩展以扩展其功能,超越其原始实现;并且可以符合协议以提供标准功能。

答案 2 :(得分:0)

Swift枚举与Objective C中的工作方式不同。

存储在其中的值不能单独使用(除非可以推断出类型)。在下面的示例中,可以推断出类型:

var myPlanet:Planet = .Mercury

首先,您告诉编译器该变量的类型为Planet,然后您可以使用简写符号。

Apple's documentation在枚举方面相当不错,我强烈建议你阅读它: