1. 程式人生 > >Swift之高階運算子與列舉

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*!)