Enumerations中的遞歸實(shí)現(xiàn)
1.基礎(chǔ)語法
起初,Swift1.2
想要支持枚舉寫法,我們通常需要自定義一個(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)值都是通過自定義類Box
來封裝的准验。正如對(duì)于表達(dá)式扔水,無非就是數(shù)字(Number),4個(gè)運(yùn)算符(+ - * /
)饱狂,需要傳入左曹步、右兩個(gè)值進(jìn)行計(jì)算。 雖說我們非常好的實(shí)現(xiàn)了枚舉中的遞歸嗡官,但是問題顯而易見箭窜,代碼過于繁瑣,不易理解衍腥。
幸運(yùn)地是swift2.0語法中考慮到了這點(diǎn)磺樱,枚舉支持遞歸寫法,只需要在case
之前寫上關(guān)鍵字indirect
即可婆咸,或者更省力的方式似乎在枚舉聲明頭enum
之前加上關(guān)鍵字indirect
即可≈褡剑現(xiàn)在來改寫下上述代碼:
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"
這種寫法才是我們所期望的,簡(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ù)來使用了倔丈!就像這樣:
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)樹
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
舉例來說:
enum Example:Int{
case A,B,C = 5,C,D
}
可以看到結(jié)果值A=0,B=1,C=5,D=6
蜜氨。
再來說說String類型械筛,倘若我們明確了rawValue
類型為String
,但是沒有給case
分配值飒炎,那默認(rèn)為怎么樣呢埋哟?
enum WeekendDay: String {
case Saturday, Sunday
}
可以看到swift2.0
為String
類型枚舉默認(rèn)值為自身名。其中WeekendDay.Saturday 就是"Saturday"郎汪,WeekendDay.Sunday就是 "Sunday"