[Swift2.0系列]枚舉中的遞歸

Enumerations中的遞歸實(shí)現(xiàn)

1.基礎(chǔ)語(yǔ)法

起初,Swift1.2想要支持枚舉寫(xiě)法,我們通常需要自定義一個(gè)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)
    }
}

// 計(jì)算( 5 + 4) * 2表達(dá)式
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

可以看到枚舉中的關(guān)聯(lián)值都是通過(guò)自定義類Box來(lái)封裝的。正如對(duì)于表達(dá)式,無(wú)非就是數(shù)字(Number),4個(gè)運(yùn)算符(+ - * /),需要傳入左、右兩個(gè)值進(jìn)行計(jì)算。 雖說(shuō)我們非常好的實(shí)現(xiàn)了枚舉中的遞歸,但是問(wèn)題顯而易見(jiàn),代碼過(guò)于繁瑣,不易理解。

幸運(yùn)地是swift2.0語(yǔ)法中考慮到了這點(diǎn),枚舉支持遞歸寫(xiě)法,只需要在case之前寫(xiě)上關(guān)鍵字indirect即可,或者更省力的方式似乎在枚舉聲明頭enum之前加上關(guān)鍵字indirect即可。現(xiàn)在來(lái)改寫(xiě)下上述代碼:

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"

這種寫(xiě)法才是我們所期望的,簡(jiǎn)潔易懂。

2枚舉知識(shí)的拓展

2.1Enumerations with Cases of Any Type

枚舉的聲明方式較為簡(jiǎn)單,如下:

enum 枚舉名稱:協(xié)議{
    case 匹配情況1
    case 匹配情況2(關(guān)聯(lián)的值類型1)
    case 匹配情況3(關(guān)聯(lián)的值類型,關(guān)聯(lián)的值類型)
}

早前的swift中關(guān)聯(lián)值可以是不同類型的,如下:

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

Swift2.0加入了有趣的東西,這些關(guān)聯(lián)了值的枚舉case,可以當(dāng)做函數(shù)來(lái)使用了!就像這樣:

enum Number {
    case Integer(Int)
    case Real(Double)
}
let f = Number.Integer
// f是一個(gè)類型為(Int)->Number 的函數(shù) 即傳入Int值 返回一個(gè)Number枚舉類型

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

2.2使用枚舉遞歸聲明節(jié)點(diǎn)樹(shù)

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

其中case Node(Tree,T,Tree)節(jié)點(diǎn)中有三個(gè)元素,分別為左節(jié)點(diǎn),節(jié)點(diǎn)值以及右節(jié)點(diǎn)。

2.3枚舉中的raw-Value類型

一般枚舉聲明時(shí)帶有raw-value的方式如下:

enum 枚舉名稱:raw-value類型,協(xié)議{
    case 枚舉情況1 = raw value1
    case 枚舉情況2 = raw value2
}

首先需要明確raw-value類型,或整數(shù)、浮點(diǎn)數(shù)、字符串當(dāng)然也可以是單個(gè)字符,總之類型必須遵循了Equatable協(xié)議。以及以下literal-convertible協(xié)議中的一個(gè):

  • IntegerLiteralConvertible(整數(shù))
  • FloatingPointLiteralConvertible(浮點(diǎn)數(shù))
  • StringLiteralConvertible(字符串)
  • ExtendedGraphemeClusterLiteralConvertible

舉例來(lái)說(shuō):

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

可以看到結(jié)果值A=0,B=1,C=5,D=6

再來(lái)說(shuō)說(shuō)String類型,倘若我們明確了rawValue 類型為String,但是沒(méi)有給case分配值,那默認(rèn)為怎么樣呢?

enum WeekendDay: String {
    case Saturday, Sunday
}

可以看到swift2.0String類型枚舉默認(rèn)值為自身名。其中WeekendDay.Saturday 就是"Saturday",WeekendDay.Sunday就是 "Sunday"

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容