美文网首页Swift 开发
Swift 高阶技巧

Swift 高阶技巧

作者: CocoaC_Wang | 来源:发表于2018-03-06 15:29 被阅读0次
    引言

    从OC转到Swift已经有接近半年了,但是很多地方都是用的最笨最基础的写法来完成,虽然代码没问题,功能能实现,不过对于想提升自己的你来说,还是得找个途径来优化自己的代码,自己维护也轻松,别人看着也舒适。正所谓不积跬步无以至千里,自己也正在一点一滴的积累,在网上看着大神们的写法,敲一遍不代码记得住,所以根据别人的文章,自己来整理并且记录知识。

    1.扩展

    要求: 求数字的平方

    // 基础写法
    func square(x:Int) -> Int {return x * x}
    var squaredNum = square(x: 5)
    square(x: squaredNum)
    

    这种写法虽然也可以完成,但是如果需要求5的4次方,就得创建一个变量,或者square(x: square(x: 5))来完成,这里可以使用扩展,链式的完成这个需求

    // 高手写法
    extension Int {
        var squared:Int { return self * self}
    }
    5.squared  // 5的平方,25
    5.squared.squared  // 5的4次方,625
    
    2. 泛型

    要求:打印输出3个数组内的所有元素

    // 基础写法
    let stringArr = ["字符串1","字符串2","字符串3"]
    let intArr = [1,2,3]
    let doubleArr = [1.0,2.0,3.0]
    func printStringArray(arr:[String]) {
        for str in arr {
            print(str)
        }
    }
    func printIntArray(arr:[Int]) {
        for i in arr {
            print(i)
        }
    }
    func printDoubleArray(arr:[Double]) {
        for i in arr {
            print(i)
        }
    }
    

    就为了输出三个数组,就得写三个方法,那要是数组种类多了怎么办,不能忍啊

    // 高手写法
    func printElemtFromArray<T>(arr: [T]) {
        for elemt in arr {
            print(elemt)
        }
    }
    
    3. Gaurd let if let

    要求:写个欢迎新用户的程序

    // 基础写法
    var myUserName: String?
    var myPassword: String?
    func userLogin() {
        if let userName = myUserName {
            if let password = myPassword {
                print("欢迎用户\(userName)")
            }
        }
    }
    

    在程序里面嵌套代码太多也是挺讨厌的,能不写就不写吧

    // 高手写法
    func userLogin() {
        guard let userName = myUserName,let password = myPassword else {
            return  // myUserName,myPassword为空时
        }
        print(userName,password)
    }
    

    4. 属性观测器

    要求:计算圆的直径

    // 基础版本
    func getDiameter(radius: Double) -> Double { return radius * 2}
    func getRadius(diameter: Double) -> Double { return diameter / 2}
    getDiameter(radius: 10) // return 20
    getRadius(diameter: 200) // return 100
    getRadius(diameter: 600) // return 300
    

    在上面我们创建了2个毫无关系的函数,可是直径和周长真的没关系吗?

    // 高手写法
    var diameter:Double = 0
    var radius:Double = 10 {
        willSet { print("装备赋值中") }
        didSet { diameter = radius * 2 }
    }
    

    willSet 会在给变量radius赋值前调用,而 didSet 会在给变量radius赋值后调用。

    5. 空合运算符

    要求:用户选择微博主题颜色

    // 基础写法
    var userChoseColor:String?
    var defaultColor = "red"
    var colorToUse = ""
    if let theColor = userChoseColor {
        colorToUse = theColor
    }else {
        colorToUse = defaultColor
    }
    

    这确实有些臃肿,来减减肥

    // 高手写法
    colorToUse = userChoseColor ?? defaultColor
    

    稍微解释下,如userChoseColor为nil,则会选择defaultColor,否则为userChoseColor。其实空合运算符就是对一下代码的简短表达方法。

    a != nil ? a! : b  //三目运算符
    
    6. 函数式编程

    要求:获取偶数

    // 基础写法
    let evensArr:Array<Int> = [1,2,3,4,5,6,7,8,9,10]
    var newEvensArr:Array<Int> = Array()
    for i in 0..<evensArr.count {
        if i % 2 == 0 {
            newEvensArr.append(i)
        }
    }
    print(newEvensArr)
    

    这种for循环真是冗长,看着就昏昏欲睡

    // 高手写法
    let newEvensArr = evensArr.filter({$0 % 2 == 0})
    print(newEvensArr)
    

    这里涉及到三种高阶函数,map,filter,reduce,以及$的含义,详情见文章《Swift 的 Map、Filter、Reduce等高阶函数,以及$的含义》

    7. 闭包 vs 函数

    要求:求两个数字的和

    // 基础写法
    func sum(x: Int, y: Int) -> Int {
         return x + y 
    }
    var result = sum(x: 5, y: 6) // 11
    

    为了这个功能我们还需要记住函数名称? 就不能直接调用属性得到值吗?当然可以

    // 高手写法
    var sumUsingClosure:(Int,Int) -> Int = { $0 + $1 }    // 用闭包替代函数
    print(sumUsingClosure(9,1))    // 10
    
    8. 遍历初始化

    要求:一个人有多少根手指和脚趾

    // 基础写法
    class Human {
        var finger:Int
        var toe:Int
        
        init(finger:Int,toe:Int) {
            self.finger = finger
            self.toe = toe
        }
    }
    
    var daDi = Human(finger: 10, toe: 10)
    daDi.finger // 10
    daDi.toe // 10
    

    因为绝大部分的人都有十根手指和脚趾,可以初始化时预先赋值

    class Human {
        var finger:Int
        var toe:Int
    
        init(finger:Int,toe:Int) {
            self.finger = finger
            self.toe = toe
        }
        
        convenience init() {
            self.init(finger: 10, toe: 10)
        }
    }
    
    var daDi = Human()
    daDi.finger // 10
    daDi.toe // 10
    

    Swift中可以在init初始化方法前加上convenience关键字,这类方法主要提供使用上的方便。

    所有的convenience 初始化方法,都必须调用同一个类中的顶级初始化方法完成初始化。另外convenience的初始化方法,是不能被子类重写或从子类中以super的方式被调用的。

    9. 延迟初始化(懒加载)

    要求:定义一个包含pi常量作为属性的类。

    \\ 基础写法
    class MathHelper {
        var pi:Double = {
            // 计算pi
            return resultOfCalculation
        }()
    }
    

    计算pi的工作量是繁重的,且对于调用者不是必须的,可以假想下MathHelper内包含数十个类pi常量的场景,如果不在使用的时候再初始化常量会浪费多少宝贵的计算资源。

    class MathHelper {
        lazy var pi:Double = {
            // 计算pi
            return resultOfCalculation
        }()
    }
    

    简单来说,就是在使用时再去加载,不使用时不会进行计算、加载

    lazy 一方面可以让初始化成本较高的变量延迟初始化,提高资源利用效率。另一方面可以延迟初始化具有外部依赖的属性变量。

    相关文章

      网友评论

        本文标题:Swift 高阶技巧

        本文链接:https://www.haomeiwen.com/subject/phphfftx.html