好像基础语法看一两个钟就可以了。。。跟其它语言相比没什么太大差别,下面的内容将相对要难一点了
一,函数
相对来说,函数可能是差别挺大的一个了
1,基本形式
func printf(str:String)->Int {
print(str)
return 0
}
printf("hello world")
swift有点像弱类型和强类型的结合体,func声明一个函数,在后面用->声明返回类型,参数里跟变量的声明类似,然后是函数体,返回值跟c一样
多参、无参、无返回值跟c一样
多参有点例外,这是在实践的时候发现的,在函数调用时,如果有多个参数,那么从第二个参数要加上label,比如:
func printf(a1:Int, b1:Int, c1:Int) {
print("a:\(a), b:\(b), c:\(c1)")
}
printf(a, b1: b, c1: c)
不要问为什么,苹果就是这么规定的,有点诡异都好,也只能记住了
写这篇博客的时候我没发现的,后来自己练的时候,报了这么一个错: missing argument label: "c1" in call 查了查才发现这个问题
2,多返回值
怎么实现多返回值一直都是c/c++的麻烦之处,swift就很方便了,返回类型改成元组即可,有写过之前循环中的元组的应用的话应该很容易接受
func printf(str:String)->(Int, String) {
print(str)
return (0, "successful")
}
print(printf("hello world"))
此外,还可以在返回值中声明元组中每一项的名称,这样就可以返回值中这么用
func printf(str:String)->(num:Int, info:String) {
print(str)
return (0, "successful")
}
let ret = printf("hello world")
print("\(ret.num) \(ret.info)")
swift有个非常贴心的特性,先看代码
func printf(bla str:String)->(num:Int, info:String) {
print(str)
return (0, "successful")
}
let ret = printf(bla: "hello world")
print("\(ret.num) \(ret.info)")
一般来说,我们在调用函数的时候,都是需要知道每个参数的意义,也就是说使用者更需要知道参数的变量名,然而大多数语言中,只有函数的定义里才有每个参数的变量名
所以swift就添加了个外部参数的特性,如上,这样在xcode里,调用该函数时,编译器会帮你补上调用者定义的外部参数名
有一点需要注意的是,如果使用了外部参数名,那在调用时就必须带上外部参数名,否则报错
4,参数默认值
这个跟c是一样的,就不说了,直接贴代码
func printf(str str:String = "blabla")->(num:Int, info:String) {
print(str)
return (0, "successful")
}
let ret = printf()
print("\(ret.num) \(ret.info)")
5,可变参数
有时候函数调用的参数数量不确定,于是swift提供了个可变参数,如下,语法就是"..."
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
不过这个可变参数没你想得那么智能,它有很多限制
首先是一个函数只能有一个可变参数,可变参数必须放在参数列表最后
然后是这个可变参数会被解释成一个相同类型的常量数组,如代码中的numbers会包含所有参数。
如果函数有一个或多个参数使用默认值,并且还具有可变参数,将可变参数放在列表的最末尾的所有默认值的参数之后。
这很好用,但没那么好用
6,变量参量
swift默认所有参数都是let常量,也就是说不给改,想使用变量参量的话,前面加个var即可,如果有外部参数,则加在外部参数前
func printf(id:Int, var bla str:String = "blabla")->(num:Int, info:String) {
print(str)
str = ""
return (0, "successful")
}
let ret = printf(0)
print("\(ret.num) \(ret.info)")
需要注意的是,如果在函数内没有改变参数的值,xcode会给出warning,建议改成let类型
7,函数类型
这是个很有趣的特性
在swift中,函数本身也是一种数据类型
var mathFunction: (Int, Int) -> Int = addTwoInts
也就是说,函数名本身也是一个变量
这就带来一个很有趣的用法
func fun(inc:(Int, Int)->Int)->Int {
return 0
}
我们就可以在一个函数里直接调用另一个函数了,这可比c++11中的函数指针要好用得多了
再给一个例子,更加地直观
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"
8,嵌套函数
swift允许嵌套函数,注意作用域即可
9,输入输出参数
这个问题和c++是一样的,函数是有作用域的,函数的参数做出的改变不能在函数外体现
如果想要一个函数可以修改参数的值,并且这些修改在函数结束调用后仍然存在,那就可以定义为输入输出参数,在参数前面添加inout关键字,这个值被函数修改后被传出函数,并替换原来的值,同时,传入的只能是变量而不能是常量,当传入的参数作为作为输入输出参数时,需要在参数面前加 & 符号,表示这个值可以被修改
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"
二,闭包
闭包简单来说就是 {}中间的代码,这个概念本身不难
1,
闭包最大的作用是简化一些函数的写法
有时候我们需要写一个函数,但是函数功能实际上只有一行,并且也只用一次,这时候我们就可以改成闭包形式
比如
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var reversed = sort(names, backwards)
我们可以这么写,这种写法实际上可以看作是一种匿名函数
var reversed = sort(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})
函数改写成闭包,形式上来说就是在 {}内 加上 () -> in,in后面接上函数内的代码即可,很好理解
事实上闭包形式还可以写成更简单的形式,比如
reversed = sort(names, { s1, s2 in return s1 > s2 } )
reversed = sort(names, { s1, s2 in s1 > s2 } )
reversed = sort(names, { $0 > $1 } )
reversed = sort(names, >)
颤抖吧,地球人
注:在swift2中,sort一改成sorted
2,trailing闭包
先把代码贴这里
let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings is inferred to be of type String[]
// its value is ["OneSix", "FiveEight", "FiveOneZero"]
map是数组的一个方法,其接受一个函数,会将数组中每一个值按你的规则转化
这段代码要看的话还是可以理解的,只是要自己写的话,呵呵
3,获取值
还是贴代码吧,这些代码都太漂亮了,初学者能看懂就不错了,要自己写还是得慢慢练
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
swift另一个很吊的地方在于,makeIncrementor返回一个函数,但这个函数是在其函数体内定义的,并且会使用函数体内的变量
不过感觉这个跟闭包好像关系不是很大