Swift 高阶技巧

引言

从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 一方面可以让初始化成本较高的变量延迟初始化,提高资源利用效率。另一方面可以延迟初始化具有外部依赖的属性变量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容