用Swift中的枚举误解

时间:2017-05-30 19:15:51

标签: swift string enums

我的城市看起来像

>>> test = {1: 2, 3: 4}
>>> a= test.iterkeys()
>>> list(a)
**[1, 3]**
>>> list(a)
**[]**
>>> list(a)
[]

我需要将带有城市名称的sting传递给等待NSString的函数之一

所以这段代码不起作用,我不明白为什么

enum Cities: String {
    case la = "Los Angeles"
    case ta = "Tel Aviv"
    case ny  = "New York"
}

我收到错误" 无法转换类型'城市'预期参数类型'字符串!' "

Xcode建议我使用Cities.ny.rawValue作为selectedCity。

4 个答案:

答案 0 :(得分:3)

Swift是强类型的

因此,当您将值传递给函数参数时,编译器会检查它是否为正确的类型。

实施例

让我们声明一个接收Int作为参数的函数

func giveMeYourAge(n: Int) {

}

现在让我们尝试调用该函数传递非Int的内容

giveMeYourAge(n: "Hello World")

现在编译器对我们生气了☠️

  

错误:无法转换类型' String'的值预期的论证类型' Int'   giveMeYourAge(n:" Hello World")

它是对的(当然)。事实上,它告诉我们,我们无法将String传递给期望Int的函数。

您的代码

当您声明枚举时(让我们按照 @Honey 的正确建议将其称为City),您需要创建一个新类型City

enum City: String {
    case la = "Los Angeles"
    case ta = "Tel Aviv"
    case ny  = "New York"
}

City来自String完全不同。 我们无法使用City代替String或反之亦然。 (就像前面的例子Int完全不同于String)。

因此,如果您的函数需要String作为参数

func myFunc(city : String) {
    // ...
}

当然,您赢了能够将City类型的值传递给它。

等待!多态性怎么样?

现在让我们来看看这段代码

class Animal { }
class Dog: Animal { }

func feed(animal: Animal) {

}

let dog = Dog()

feed(animal: dog)

为什么这段代码会编译???

这称为多态性。我们写的时候

 class Dog: Animal { }

我们定义了一种比Dog更具体的新类型(Animal)。

多态允许我们传递给期望Animal作为参数的函数,这是更具体的(如Dog)。

然而,多态与您的示例无关。即使语法相似。

使用此语法定义枚举时

enum City: String { ... }
  • NOT 定义String的子类型。
  • 创建比String更具体的内容。
  • 使用多态。

相反,您只是创建一个新类型City,它具有rawValue类型的实例属性(String)。

答案 1 :(得分:2)

您需要指定原始值才能使用字符串文字,因为没有它,您只需要引用枚举本身。

let selectedCity = Cities.ny.rawValue

答案 2 :(得分:1)

这就像你试图访问一个类实例,而不是实例的属性。它不会起作用。具体你在这里尝试访问枚举本身是不正确的。您应该访问其rawValue 属性

来自Apple

  

使用rawValue访问枚举大小写的原始值   的属性

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

答案 3 :(得分:0)

我有更好的解决方案,这更合理......因此你这样做:

enum Cities {

    case la
    case ta
    case ny

  var cityString: String{
    switch self{
    case la:
    return "Los Angeles"
    case ta:
    return "Tel Aviv"
    case ny:
    return "New York"
        }
    }
}

现在你需要打电话:

let selectedCity = Cities.ny.cityString
我投票反对其他想法背后的原因是,rawValues应该用于识别案件,而不是用于获取它们的价值......但这只是我的意见:))