[Swift2.0系列]枚举中的递归

作者: NinthDay | 来源:发表于2015-09-19 13:41 被阅读818次

Enumerations中的递归实现

1.基础语法

起初,Swift1.2想要支持枚举写法,我们通常需要自定义一个Box类用于封装需要传入的值,如下:

class Box<T>{
    let unbox:T
    init(_ value:T){self.unbox = value}
}

enum ArithmeticExpression<T>{
    case Number(T)
    case Addition(Box<ArithmeticExpression<T>>,Box<ArithmeticExpression<T>>)
    case Multiplication(Box<ArithmeticExpression<T>>,Box<ArithmeticExpression<T>>)
}

func evaluate(expression:ArithmeticExpression<Int>)->Int{
    switch expression{
    case .Number(let value):
        return value
    case .Addition(let left, let right):
        return evaluate(left.unbox) + evaluate(right.unbox)
    case .Multiplication(let left, let right):
        return evaluate(left.unbox) * evaluate(right.unbox)
    }
}

// 计算( 5 + 4) * 2表达式
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let two = ArithmeticExpression.Number(2)
let sum = ArithmeticExpression.Addition(Box(five), Box(four))
let product = ArithmeticExpression.Multiplication(Box(sum), Box(two))
print(evaluate(product))//输出18

可以看到枚举中的关联值都是通过自定义类Box来封装的。正如对于表达式,无非就是数字(Number),4个运算符(+ - * /),需要传入左、右两个值进行计算。 虽说我们非常好的实现了枚举中的递归,但是问题显而易见,代码过于繁琐,不易理解。

幸运地是swift2.0语法中考虑到了这点,枚举支持递归写法,只需要在case之前写上关键字indirect即可,或者更省力的方式似乎在枚举声明头enum之前加上关键字indirect即可。现在来改写下上述代码:

indirect enum ArithmeticExpression {
    case Number(Int)
    case Addition(ArithmeticExpression, ArithmeticExpression)
    case Multiplication(ArithmeticExpression, ArithmeticExpression)
}

func evaluate(expression: ArithmeticExpression) -> Int {
    switch expression {
    case .Number(let value):
        return value
    case .Addition(let left, let right):
        return evaluate(left) + evaluate(right)
    case .Multiplication(let left, let right):
        return evaluate(left) * evaluate(right)
    }
}

// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// prints "18"

这种写法才是我们所期望的,简洁易懂。

2枚举知识的拓展

2.1Enumerations with Cases of Any Type

枚举的声明方式较为简单,如下:

enum 枚举名称:协议{
    case 匹配情况1
    case 匹配情况2(关联的值类型1)
    case 匹配情况3(关联的值类型,关联的值类型)
}

早前的swift中关联值可以是不同类型的,如下:

enum Number {
    case Integer(Int)
    case Real(Double)
}

Swift2.0加入了有趣的东西,这些关联了值的枚举case,可以当做函数来使用了!就像这样:

enum Number {
    case Integer(Int)
    case Real(Double)
}
let f = Number.Integer
// f是一个类型为(Int)->Number 的函数 即传入Int值 返回一个Number枚举类型

let evenInts:[Number] = [0,2,4,6].map(f)// 就能得到[.Integer(0),.Integer(2),.Integer(4),.Integer(6)]

2.2使用枚举递归声明节点树

enum Tree<T>{
    case Leaf
    indirect case Node(Tree,T,Tree)
}

其中case Node(Tree,T,Tree)节点中有三个元素,分别为左节点,节点值以及右节点。

2.3枚举中的raw-Value类型

一般枚举声明时带有raw-value的方式如下:

enum 枚举名称:raw-value类型,协议{
    case 枚举情况1 = raw value1
    case 枚举情况2 = raw value2
}

首先需要明确raw-value类型,或整数、浮点数、字符串当然也可以是单个字符,总之类型必须遵循了Equatable协议。以及以下literal-convertible协议中的一个:

  • IntegerLiteralConvertible(整数)
  • FloatingPointLiteralConvertible(浮点数)
  • StringLiteralConvertible(字符串)
  • ExtendedGraphemeClusterLiteralConvertible

举例来说:

enum Example:Int{
    case A,B,C = 5,C,D
}

可以看到结果值A=0,B=1,C=5,D=6

再来说说String类型,倘若我们明确了rawValue 类型为String,但是没有给case分配值,那默认为怎么样呢?

enum WeekendDay: String {
    case Saturday, Sunday
}

可以看到swift2.0String类型枚举默认值为自身名。其中WeekendDay.Saturday 就是"Saturday",WeekendDay.Sunday就是 "Sunday"

相关文章

  • [Swift2.0系列]枚举中的递归

    Enumerations中的递归实现 1.基础语法 起初,Swift1.2想要支持枚举写法,我们通常需要自定义一个...

  • WWDC2015Session106What's New

    新特性:基本类型、类型匹配、可检查性、协议扩展、错误处理 基本类型 枚举 在枚举中加入类型: 递归枚举递归枚举中需...

  • Swift - 递归枚举

    个人理解 递归枚举是拥有另一个枚举作为枚举成员关联值的枚举,实际上就是Swift中枚举关联值的特性和递归算法在Sw...

  • 可暴力枚举就是可计算

    递归可枚举就是计算可枚举

  • Swift 5.x 递归 enum

    递归枚举是拥有另一个枚举作为枚举成员关联值的枚举.当编译器操作递归枚举时必须插入间接寻址层.你可以在声明枚举成员之...

  • Swift 5.1 (8) - 枚举类型

    级别: ★☆☆☆☆标签:「iOS」「Swift 5.1」「枚举」「迭代枚举」「枚举关联值」「递归枚举」作者: 沐灵...

  • 枚举(Enum)

    目录 枚举语法 关联值 原始值 递归枚举 ** 在 Swift 中不必给每一个枚举成员提供一个值,如果给枚举成员提...

  • Swift 2 学习笔记 10.枚举

    课程来自慕课网liuyubobobo老师 枚举 枚举基础 枚举之原始值 枚举之关联值 枚举递归

  • 03.Swift学习

    枚举 关联值 1.有时候会将枚举的成员值跟其他类型的关联存储在一起 原始值 隐式原始值 递归枚举 使用递归枚举的时...

  • 递归可枚举、递归

    图灵机对于任意输入,只有三种状态: 1.接受停机。 2.状态转移函数无定义,落空停机。 3.一直有定义,但永不停机...

网友评论

    本文标题:[Swift2.0系列]枚举中的递归

    本文链接:https://www.haomeiwen.com/subject/ofnbcttx.html