Swift花边知识点

大概内容

递归,异常,索引,断言

递归

//求C(m,n)函数m!/n!/(m-n)! = m!/(n!*(m-n)!)或者n*(n-1)!
func Cmn(m:Int, _ n:Int) ->Int{
    assert(m >= n,"m必须大于等于n")//断言,m小于n时提示用户"m必须大于等于n"
    return  Int(a3(m) / a3(n) / a3(m - n))
}
/*
//n*(n-1)! 采用递归方法,效率没有采用循环的效率高
func f(n:Int) -> Double{
    if n == 0 || n == 1{
        return 1
    } //收敛
    return Double(n) * f(n - 1)//条件
}

//函数递归调用(一个函数直接或者间接的调用自身),采用递归方法,效率没有采用循环的效率高,能用循环写出的就用循环,很麻烦很复杂的问题可以采用递归
//使用递归必须要有
//1.递归公式
//2.收敛条件
*/

//用递归计算1-n的和
func sum(n:Int) -> Int{
    if n == 1{
        return 1
    }
    return n + sum(n - 1)
}

异常

Fraction 分数类

//x和y的最大公约数跟y%x的最大公约数是一样的(欧几里得算法)
//求最大公约数
func gcd(x:Int, _ y:Int) ->Int{
    if x > y{
        return gcd(y, x)
    }
    else if y % x != 0{
        return gcd(y % x, x)
    }
    else {
        return x
    }
}

//定义一个遵循ErrorType协议的枚举
//通过不同的case定义程序中可能出现的若干异常状况

/**
- ZeroDenominator:分母为0
- DividByZero:除数为0
*/
enum FractionError:ErrorType{
    case ZeroDenominator,DividByZero
}

class Fraction{
    private var _num:Int //分子
    private var _den:Int //分母
    
    
//   如果一个方法抛出了异常,那么在声明方法时必须写上throws关键字
    init(num:Int,den:Int) throws {
        _num = num
        _den = den
//        如果程序中出现问题就抛出异常
//        被throw关键字抛出的必须遵循ErrorType协议
        if _den == 0{
            throw FractionError.ZeroDenominator
        }
        else{
            normoalize()
            simplify()
        }
    }

    var info:String{
        get {
            return _num == 0 || _den == 1 ? "\(_num)" : "\(_num)/\(_den)"
        }
    }
    
    
    func add(other:Fraction) throws -> Fraction{
        return try Fraction(num: _num * other._den + other._num * _den, den: _den * other._den)
       
        
    }
    
    func sub(other:Fraction) throws ->Fraction{
        return try Fraction(num: _num * other._den - other._num * _den, den: _den * other._den)
        
        
    }

    func mul(other:Fraction) throws ->Fraction{
        return try Fraction(num: _num * other._num, den: _den * other._den)
    }
    
    func div(other:Fraction) throws ->Fraction{
        if other._num == 0{
            throw FractionError.DividByZero
        }
        return try! Fraction(num: _num * other._den, den: _den * other._num)
    }
    
    func normoalize() ->Fraction{
        if _den < 0{
            _num = -_num
            _den = -_den
        }
        return self
    }
    
    func simplify() ->Fraction{
        if _num == 0{
            _den = 1
        }
        else{
            let x = abs(_num)
            let y = abs(_den)
            let g = gcd(x, y)
            _num /= g
            _den /= g
        }
        return self //返回本身的分数对象
    }
    
}

//运算符重载 (为自定义的类型定义运算符)
func +(one:Fraction,two:Fraction) -> Fraction{
//    如果能够保证方法调用时不出现异常那么可以在try后面加!
//    这样就可以在不写do...catch的情况下调用可能出状况的方法
    return try! one.add(two)
}

func -(one:Fraction,two:Fraction) -> Fraction{
    return try! one.sub(two)
}

func *(one:Fraction,two:Fraction) -> Fraction{
    return try! one.mul(two)
}

func /(one:Fraction,two:Fraction) throws -> Fraction{
    return try one.div(two)
}

测试

//对于可能出状况的代码要放到do...catch语句中
//在可能出状况的代码前面还要加上try,表示尝试执行
//如果在do中的代码没有出任何状况那么catch就不会执行
//如果do中出现状况,代码就不会继续往下执行,而是转移到catch中
//在do的后面可以跟上多个catch用于捕获不同的状况,但是最多只有一个catch会被执行
do {
    let f1 = try Fraction(num: 3, den: 0)
    let f2 = try Fraction(num: 0, den: 5)
    
    let f3 = f1 + f2
    print(f3.info)
    let f4 = f1 - f2
    print(f4.info)
    let f5 = f1 * f2
    print(f5.info)
    let f6 = try f1 / f2
    print(f6.info)
}
catch FractionError.ZeroDenominator{
    print("分母不能为0")
}
catch FractionError.DividByZero{
    print("除数不能为0")
}
catch{
    print("出错了,我也不知道什么问题")
}

//不想写do...catch时也可以写成下面的代码
func foo(){
//    如果能保证代码不出错可以在try后面加!
//    如果不能保证代码是否会出错可以在代码后面加?
//    需要注意的是由?的地方会产生optional
//    稍后可能还需要对可空类型进行拆封且方式有二:
//    1.不安全的做法:xxx!
//    2.安全的做法:有if let = xxx
    let f1 = try? Fraction(num: 3, den: 0)
    let f2 = try? Fraction(num: 0, den: 5)
    
//    let c = f1! + f2!  //不安全
    
//    安全
    if let a = f1, b = f2{
        let c = a + b
        print(c.info)
    }
    else{
        print("无效的分数不能运算")
    }
}

索引

例子1

片段代码,详细参考gobangApp改进版

//建立索引****
    subscript(row:Int,col:Int) -> Bool{
        get{ return board[row][col] == .Space }
        set(isBlack){
            if board[row][col] == .Space{
                board[row][col] = isBlack ? .Black : .White
                isBlackTurn = !isBlackTurn
            }
        }
    }

测试

if board[row,col]{
                board[row,col] = board.isBlackTurn
                setNeedsDisplay()
}

例子2:生成随机验证码

func randomNum(min:Int,_ max:Int) -> Int{
   return Int(arc4random_uniform(UInt32(max - min)) + 1) + min
}

//扩展原生API
extension String{
    var lenth: UInt32 {
        get{ return UInt32(self.characters.count) }
    }
    //建立索引
    subscript(index:Int) -> Character{
        get { return self[self.startIndex.advancedBy(index)] }
    }
}

func generate(lenth:Int) ->String{
    var code = ""
    if lenth > 0{
        let str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        for _ in 0..

断言

当需要判断是否满足某个条件时可以使用断言assert,满足条件程序继续执行,不满足就提示逗号后面的内容。

let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// this causes the assertion to trigger, because age is not >= 0

你可能感兴趣的:(Swift花边知识点)