Swift之高階運算子與列舉
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
//位運算子
//UInt8,將十進位制數以二進位制的方式賦值,UInt8型別是8位無符號整型,也就是說,任何一個UInt8型別的變數都是採用8個二進位制位來儲存資料的。因此下面的a變數的實際儲存資料為0b00000111。位運算的實質就是對資料的每一個二進位制位進行邏輯運算
var a:UInt8 = 0b111
a = 0b100
//~取反,&位與,|位或,^異或,<<左移,
a = ~a//00000100 ->11111011 255-4 = 251
a = 0b1001 & a//11111011 & 00001001 = 00001001 ->9
a>>1// 00001001 >>1 = 00000100 ->4
a<<1//00001001 <<1 = 00010010 ->18
a = a<<1 // 18
//注意,進行按位左移或右移運算的時候,有可能出現丟失資料位的情況,例如對於UInt8型別,將 00001111 向左移6位,變成了 110000000
//溢位運算子
//在Swift語言注重安全性,在編寫程式碼時,如果出現了資料溢位,會直接出現執行時報錯。而溢位運算子這種設計將程式碼的不確定性降低了許多。所謂溢位,就是超出資料型別的最大值或者最小值,以UInt8為例,最大值為255,加1就會溢位
/*
var b:UInt8 = 255
b=b+1
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
*/
//如果需要溢位操作,就要使用溢位操作符&
var b:UInt8 = 255
b = b &+ 1//支援溢位的加操作後,b的值為0
b = b &- 1 //255
b = b &* 2 //乘操作
//注意:對於二進位制資料進行乘2運算,實質就是對二進位制資料進行左移一位的運算。例如二進位制資料 11111111*2 = 1111110
//運算子的過載與自定義
//定義一個形狀列舉
enum Shape{
case circle(center:(Double,Double),radius:Double)//通過圓心和半徑建立圓形
case rect (width:Double,height:Double,center:(Double,Double))//設定矩形的寬、高、中心點
case trangle (point1:(Double,Double),point2:(Double,Double),point3:(Double,Double))//三角的三個角點
}
//這樣在建立的時候,直接提供所需的引數即可
var circle = Shape.circle(center: (20, 20), radius: 20)
var rect = Shape.rect(width: 10, height: 10, center: (40, 40))
var trangle = Shape.trangle(point1: (20, 20), point2: (50, 90), point3: (30, 50))
//在switch-case結構語句中,匹配到列舉後,可以通過引數捕獲的方式來獲取列舉例項的相關值
func shapeFunc(param:Shape){
switch param {
case let .circle(center,radius):
print("圓形:中心點\(center),半徑\(radius)")
case let .rect(center,width,height):
print("矩形:中心\(center),寬度\(width),高度\(height)")
case let .trangle(point1, point2, point3):
print("三角的頂點:\(point1)、\(point2)、\(point3)")
}
}
shapeFunc(param: circle)
shapeFunc(param: trangle)
shapeFunc(param: rect)
//遞迴列舉
/*
遞迴是一種程式碼演算法技巧,遞迴演算法的效率十分高,但是其效能資源的耗費也十分嚴重。函式的功能是進行資料計算,遞迴函式只是使用遞迴的演算法來進行資料的計算。列舉的功能是資料的描述。因此,遞迴列舉的作用就是使用遞迴的方式來進行資料描述。
*/
//使用列舉模擬加減乘除四則運算
enum Expression {
// 描述單個數字
case num(param:Int)
// 表示加法,將Expression作為相關值引數型別,使用indirect關鍵字修飾的列舉值表示這個列舉是可遞迴的
indirect case add(param1:Expression,param2:Expression)
indirect case sub(param1:Expression,param2:Expression)
indirect case mul(param1:Expression,param2:Expression)
indirect case div(param1:Expression,param2:Expression)
}
//運算((5+5)*2-8)/2
var num5 = Expression.num(param:5)
//5+5
var num55 = Expression.add(param1: num5, param2: num5)
//2
var num2 = Expression.num(param: 2)
//(5+5)*2
var numMul = Expression.mul(param1: num55, param2: num2)
//8
var num8 = Expression.num(param: 8)
// -8
var numsub8 = Expression.sub(param1: numMul, param2: num8)
// /2
var resultNum = Expression.div(param1: numsub8, param2: num2)
//這樣result就是對((5+5)*2-8)/2的描述,在開發中要將描述和運算結合,能夠編寫出優美的程式碼,處理遞迴列舉通常採用遞迴函式,這樣就可以通過描述的表示式進行計算
func ExpressionFunc(param:Expression) -> Int{
switch param {
case let .num(param):
return param
case .add(let param1, let param2):
return ExpressionFunc(param: param1)+ExpressionFunc(param: param2)
case .sub(let param1, let param2):
return ExpressionFunc(param: param1) - ExpressionFunc(param: param2)
case .mul(let param1, let param2):
return ExpressionFunc(param: param1) * ExpressionFunc(param: param2)
case .div(let param1, let param2):
return ExpressionFunc(param: param1) / ExpressionFunc(param: param2)
}
}
print(ExpressionFunc(param: resultNum))//最後的計算結果是6
//1、模擬C語言通過自定義運算子的方式實現字首自增、字首自減、字尾自增、字尾自減
prefixoperator ++ //宣告字首++
postfixoperator ++ //聲明後綴++
prefixoperator -- //宣告字首--
postfixoperator -- //聲明後綴--
prefix func ++ (param:inout Int ) ->Int{
param += 1
return param
}
prefix func -- (param: inout Int)->Int{
param -= 1
return param
}
postfix func ++(param: inout Int)->Int{
param += 1
return param - 1
}
postfix func -- (param: inout Int ) -> Int{
param -= 1
return param + 1
}
var a2 = 5
print(a2++)
//2、Swift語言中的加法運算子不能支援對區間範圍的相加操作,過載加法運算子,使其支援區間的追加,例如(0...5)+6後的計算結果為區間0...11
func + (param:ClosedRange<Int>,param2:Int)->ClosedRange<Int>{
return param.lowerBound...param.upperBound+param2
}
var newRange = 0...5+6//0...5 ->param,6->param2
print(newRange)//0...11
//3、自定義階乘運算子
postfixoperator *!
postfix func *! (param:Int)->Int{
if param <= 0 {
return 0
}
var tem = param
var result = 1
while tem>1 {
result *= tem
tem -= 1
}
return result
}
print(5*!)