一直在用OC写代码,对swift没有什么研究,一直想着不就一个新语言嘛,到用的时候顺便学习一下规则就行了,api那不就是那些,他swift还能玩出花儿来...
然后接下来的悲剧大家也能猜到了,真正想看的时候完全看不懂...
每天看着语言排行榜上OC每况愈下,swift 像个青春期的骚年一样蹭蹭蹭往上长,我这个拙计呀!
江湖有传言说swift比OC容易,经过这几天的了解,我感觉不尽然,至少我不敢这么说..
在我看来,swift 犹如暴雪的游戏一般,容易上手,难于精通。OC的规则有些死板,像是一个有限的空间,即便是高手,也只能在这里玩(虽然有些按耐不住去玩runtime),一般人感觉自己也在这个空间似乎与高手差别不大,至少读大神的源码坎儿不多。但swift就不一样了,太灵活,将来必成各种高手炫技虐菜的血腥战场...如果我还是拿着OC翻译swift的思路来写代码,早晚成刀下之鬼,饭碗怎么丢的都不知道...
像是函数这种,在OC里面一直规规矩矩的东西,硬是被swift玩残了,看代码的时候只想爆粗口,这他么什么东西,这他么又是什么东西!写代码的时候,我擦,怎么又报错!这样都不行?!现在在读 Matt Neuburg 的 <iOS 9 Programming Fundamentals> ,函数这一章讲的细致入微,心中有些了然,且分享出来给大家,内容多出自此书,自己只是梳理一下,还希望多多指正。
完整书写形式 一个简单动画函数
func animationAction () {
self.view.backgroundColor=UIColor.redColor()
}
func completion ( finished :Bool) ->Void{
print("Animation Completed !!")
}
UIView.animateWithDuration(2.0, animations:animationAction, completion:completion)
简化步骤1 : 将作为参数的函数变成无名函数 Anonymous Function
通常,在函数不需要重用,而且又仅仅作为参数传递给另一个函数的情况下,我们可以省略他的函数名,变成无名函数
变化规则:
a. 省略函数名 保留花括号 {}
b. 把参数列表和返回参数 (即函数类型) 写在{}第一行
c. 用 in 将 函数类型 与 函数体 区分开来
经过步骤1,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
() ->Void/*函数类型*/ in
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
(finished :Bool) ->Void /*函数类型*/ in
print("animationCompleted")//函数体
})
简化步骤2:
省略返回类型, 当编译器已知该函数返回类型的时候
经过步骤2,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
() /*函数类型*/ in
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
(finished :Bool) /*函数类型*/ in
print("animationCompleted")//函数体
})
简化步骤3: 省略参数列表和in, 当没有参数的时候
经过步骤3,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
(finished :Bool)/*函数类型*/ in
print("animationCompleted")//函数体
})
简化步骤4: 省略参数类型和参数列表括号,当编译器已知参数类型的时候
经过步骤4,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
finished/*函数类型*/ in
print("animationCompleted")//函数体
})
简化步骤5: �省略 函数类型和in ,并使用$0,$1等访问参数,当编译器已知参数类型的时候
经过步骤5,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
//省略函数类型和in
print("animationCompleted\($0)")//直接访问变量,
})
简化步骤6: �省略 函数类型和in ,不访问函数参数
规则: 使用下划线 _ 代替整个参数列表
经过步骤6,简化后的代码如下:
UIView.animateWithDuration(2.0, animations: {
self.view.backgroundColor=UIColor.redColor()//函数体
}, completion: {
_-> () in
//or 继续省略返回类型
// _ in
print("animationCompleted")//不需要引用任何参数
})
注:通过步骤5和6,说明一个规律。作者原文如下:
But note that if the anonymous function takes parameters, you must acknowledge them somehow. You can omit the in line and use the parameters by the magic name $0 and so on, or you can keep the in line and ignore the parameters with an underscore, but you can't omit the in line altogether and not use the parameters by their magic names! If you do, your code won't compile.
中文(当然是自己翻译的):
如果一个无名函数有参数,你必须以下面两种方式之一告知编译器。
当你需要引用变量的时候,可以省略函数类型和in ,使用$x访问这些变量;
当你无需引用变量的时候,保留 in 使用 _ 代替参数列表。
不能省略函数类型和in的同时,还不使用$n 引用变量,这样将不能编译通过。
简化步骤7: �省略无名函数的caller函数的参数名称 (trailing function syntax)
规则: 当且仅当无名函数作为caller函数的最后一个参数的时候,
可以省略最后一个参数名称(即把caller函数结束标志的 ")" 放在倒数第二个参数的末尾)
将此无名函数紧跟在 ")" 后面,作为最后一个参数
经过步骤7,简化后的代码如下 (也是我们简化此函数调用的最终形态):
UIView.animateWithDuration(2.0, animations: {
self.view.backgroundColor=UIColor.redColor()//函数体
}) { //提前结束函数括号 ")" 并把此无名函数紧跟其后
_in
print("animationCompleted")//函数体直接访问变量
}
其他简化规则
- 如果caller函数有且仅有一个参数,需要传入一个function的时候,你可以省略函数调用使用的括号(),这是swift函数调用的语法中,唯一可以省略()的情况。
例子:
func callAnotherFunction( aFunc : () -> ()) {
aFunc()
}
callAnotherFunction{ //这里省略了调用函数的()
print("This is the function as the only parameter")
}
- 省略有返回值函数的 return
规则: 当函数体有且仅有一行(分号隔开不算哦..就是一个表达式),而且该行作为表达式的值的类型与函数返回类型一致的时候,
编译器会默认该行的值就是你要返回的值
例子1:
func sayHowdy () ->String{
return"Howdy"
}
func perfermAndPrint (f: () ->String) {
lets = f()
print(s)
}
perfermAndPrint{
sayHowdy()//默认返回该行的值等效于return sayHowdy()
}
例子2: 数组的map 函数
let numArr = [1,2,3,4]
//完整写法
let tripleArr =numArr.map({(n :Int) ->Intin
return n *3
})
print(tripleArr)// [3,6,9,12]
//等效简写
let doubleArr = numArr.map{
n in
n *2
}
print(doubleArr)//[2,4,6,8]
//省略 in 的简写
let tenthArr = numArr.map{10* $0 }
print(tenthArr) // [10, 20, 30, 40]
第一次分享,如有不足还请多多指正。