Swift3.0 - 枚举

基本用法

  • 最简单的定义

a.多行写法

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

b.单行写法

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

提示:

Swift 3.0 开始,定义枚举值,统一小写

  • 指定枚举类型的原始数据类型
enum Rank: Int{ // Int 设置枚举值的类型
// 定义枚举值设置值
case ace
// 可以case 后面一次定义多个枚举值
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king

// 定义函数 如果多人合作的时候,可以使用这个让别人更加了解你定义的属性的含义
    func simpleDescription() -> String {
        switch self { // self 就是这个枚举本身
            case .ace:
                return "ace1"
            case .jack:
                return "jack1"
            case .queen:
                return "queen1"
            case .king:
                return "king1"
            default:
                return String(self.rawValue)
        }
    } 
}

注意

枚举类型可以Int String等基本类型的值,对象是不可以的,官方说必须是实现RawRepresentable 协议的类型才可以

  • 使用
  let ace = Rank.ace // 非可选值
  let rank = Rank(rawValue: 1)

提示

第二种创建的枚举为可选类型,这样设计的原因是,你有可能创建一个nil对象,处于安全考虑它也必须是可选值,使用的时候要解包

  • 给枚举设置原始值
enum CompassPoint {
    case north = "1"
    case south = "2"
    case east = "3"
    case west = "4"
}

提示:

你认为上面这样定义是否是正确的,答案是否定的,因为系统不知道你枚举的原始值是什么类型的,这里系统没有进行类型推断,所有我们要给枚举添加原始值之前,必须指定枚举原始值的类型,如下

enum CompassPoint:Character{
    case north = "1"
    case south = "2"
    case east = "3"
    case west = "4"
}
  • 获取原始值
let aceRawValue = ace.rawValue

提示

1.如果你没有定义枚举的原始值类型,你不能通过上述方法获取原始值 2.输入定义的是数字类型 ,原始值对应的是数字本身, 3.如果定义的是字符串类型,但你没有給它赋值,这个时候,你获取的原始值就是你定义的名字

高级用法

  • 提供值创建枚举
enum ServerResponse {
  case result(String, String)
  case failure(String)
}
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")

提示

这个方式定义的枚举 不能使用 == 来做判断处理,我们应该使用模式匹配的方式处理,这种定义方式强调的是传值,如下

switch success {
case let .result(sunrise, sunset): // 模式匹配
    print("Sunrise is at \\(sunrise) and sunset is at \\(sunset).")
case let .failure(message):
    print("Failure...  \\(message)")
}

// 或者
switch success {
case  .result(let sunrise, let sunset): // 模式匹配
    print("Sunrise is at \\(sunrise) and sunset is at \\(sunset).")
case  .failure(let message):
    print("Failure...  \\(message)")
}
  • indirect 使用方法 使用场景:

主要用于递归枚举,看下面例子,你应该很清楚怎么使用

a.使用方式1

enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let expression =     ArithmeticExpression.addition(ArithmeticExpression.number(3),     ArithmeticExpression.number(4))

b.使用方式2

 indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let expression =     ArithmeticExpression.addition(ArithmeticExpression.number(3), ArithmeticExpression.number(4))

结论:

如果你定义的枚举是递归的形式,必须有关键字indirect 修饰,不然系统会编译报错哦!

  • 重新实现SWIFT标准库的可选类型(使用泛型技术)
enum OptionalValue<Wrapped> {
    case none
    case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
  • 枚举可以继承协议
protocol Skill{
    mutating func modifyMusic(name:String)
}

enum Type:String,Skill{
case name = "123"
mutating internal func modifyMusic(name: String) {
    self = Type(rawValue: "123")!
}
}
  • 枚举不能包含存储属性,但是可以包含静态变量和计算属性
enum SomeEnumeration:Int {
    case one = 2
    case two = 345
    // 静态变量
    static  var storedTypeProperty = "Some value."
    // 静态计算属性
    static var computedTypeProperty: Int {
        return 6
    }
    // 计算属性
    var getRaw:Int{
        return self.rawValue
    }
}
  • 一般人都不知道的神级操作
enum Locale {
    case none
    case base
    case language(String)
 }

我们创建一个变量

let locale = Locale.language("english")

问题: 我们怎么判断它是什么类型呢?

if locale == Locale.base {
}// 错误的判断方式

编译错误,如果没有 case language(String) 这种赋值枚举,可以使用上面的方式,一点问题也没有,但是如果有这种类型,系统不允许使用 == 进行数据判断的

我们可以提供下面的方式进行判断

switch locale{
    case Locale.base : print(locale)
    case Locale.none : print(locale)
    case Locale.language("english"): print(locale)
    case Locale.language(let x):print(x)
}

为了判断一个类型我们写这么一个判断是在是有点不雅,下面就体验一下关键字case 的神奇用法

我们重新写一下上面的枚举,使用case 写出优雅的代码

enum Locale {
    case none
    case base
    case language(String)
    // 判断是否是汉语
    var isChinese:Bool{
        if case .language("chinese") = self {
            return true
        }
      return false
    }
    // 是否是其他语言
     var isLanguage:Bool{
      if case .language = self {
          return true
      }
        return false
    }

    var isBase: Bool {
        if case .base = self {
            return true
        }
    
        return false
    }

    var isNone: Bool {
        if case .none = self {
            return true
        }
        return false
    }
}

我们看一下如何调用

let locale = Locale.language("english")
print(locale.isChinese)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏石奈子的Java之路

原 java数据结构与算法之数组篇

2114
来自专栏于晓飞的专栏

Java 泛型进阶

在 List<String> 中添加 Integer 将不会通过编译,但是List<Sring>与List<Integer>在运行时的确是同一种类型。

2193
来自专栏一“技”之长

Swift3.0带来的变化汇总系列二——集合类型中的变化

    与字符串类似,Swift中集合的类型在3.0版本中也做了大量API上面的修改。

901
来自专栏noteless

-1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器

                        数组可以是基本类型,也可以是引用类型

1302
来自专栏java一日一条

JAVA集合类(大公司面试喜欢问的)

看了一些所谓大公司的Java面试问题,发现对于JAVA集合类的使用都比较看重似的,而自己在这方面还真的是所真甚少,抽空也学习学习吧。

1082
来自专栏彭湖湾的编程世界

【算法】实现栈和队列

栈(stack) 栈(stack)是一种后进先出(LIFO)的集合类型, 即后来添加的数据会先被删除 ? 可以将其类比于下面文件的取放操作:新到的文件会被先取走...

3476
来自专栏偏前端工程师的驿站

Java魔法堂:解读基于Type Erasure的泛型

一、前言                               还记得JDK1.4时遍历列表的辛酸吗?我可是记忆犹新啊,那时因项目需求我从C#转身到Jav...

2265
来自专栏郭耀华‘s Blog

Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法

Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法 ArrayList 和Vector是采用...

3988
来自专栏一个会写诗的程序员的博客

《Kotlin 极简教程 》第6章 泛型

通常情况的类和函数,我们只需要使用具体的类型即可:要么是基本类型,要么是自定义的类。

1253
来自专栏苦逼的码农

【链表问题】删除单链表的中间节点

以专题的形式更新刷题贴,欢迎跟我一起学习刷题,相信我,你的坚持,绝对会有意想不到的收获。每道题会提供简单的解答,如果你有更优雅的做法,欢迎提供指点,谢谢。

1074

扫码关注云+社区

领取腾讯云代金券