美文网首页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