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.0
為String
類型枚舉默認(rèn)值為自身名。其中WeekendDay.Saturday 就是"Saturday",WeekendDay.Sunday就是 "Sunday"