函数
函数的种类和声明
Global Functions
在文件中的任何地方都可以调用,比如:
print("I'm a global function!")
Method
在某个class里声明,需要用对象来调用,比如
let array = ["A", "13", "B","5","87", "t", "41"]
class Arithmetic {
func sumOfStrings(aBunchOfStrings: [String]) -> Int {
let array = aBunchOfStrings
var sum = 0
for string in array {
if Int(string) != nil {
let intToAdd = Int(string)!
sum += intToAdd
}
}
return sum
}
}
函数的声明
func functionName (parameterName: parameterType) -> returnType {
statements to execute
return object
}
外部参数名
func functionName (externalParameterName localParameterName: parameterType) -> returnType {
statements to execute
return object
}
比如
func area (宽 width:Double ,高 height:Double ) ->Double {
return width * height
}
print (area(宽:3.4,高:4.7)) //宽和高为外部函数名
函数的参数
数组参数
func sum(numbers:Int...)->Int {
var total: Int = 0
for num in numbers {
total += num
}
print(total)
return total
}
sum(1,3,4,5)
- 在参数类型后面添加…表示该参数可以接受多个参数值
- 一个函数当中只有一个数组参数,并且位于列表的最后
默认参数
1 | func sayHi(msg:String, name:String="Lily"){ |
忽略形参名,添加下划线 _
1 | func sayHi(msg:String, _name:String="Lily"){ |
如果函数里有可变参数也有默认参数,数组参数放在最后面,默认参数出现在次后面
变量形参
因为传入的参数是常量,如果需要在函数内进行变动数据的话,需要先设个变量 (swift 3)
func placeFirstLetterLast(myString: String) -> String {
var newString = myString
newString.append(firstCharacterOf(word: myString))
newString.removeAtIndex(myString.startIndex)
return newString
}
placeFirstLetterLast("Mom")
swift2的解决办法。swift3将取消
//这里的形参是个变量,如果去掉var就是个常量,因为形参默认是常量constant
func factorial(var number:Int) -> Int{
var result:Int = 1
while number > 1 {
result = result * number
number -= 1
}
return result
}
print(factorial(3))
In-out形参
func swap (inout a:Int, inout b:Int){
let tmp = a
a = b
b = tmp
}
var a:Int = 1
var b:Int = 3
swap(&a,&b)
print("交换之后的结构为:a=\(a),b=\(b)")
- In-out参数就是强制传递变量的指针,因为在swift里,大多是值类型,而不是指针类型
- 只能传入变量作为实参
- 输入输出不能带有默认值
- 如果你用关键字inout标记了一个参数,这个参数不能再用var或者let去标记
函数返回值
void
没有指定返回类型的函数总返回void,在swift中,void可以理解为空元组
func sayHi2(){
print("welcome")
}
sayHi2()
多个返回值
func area(width:Double,height:Double)->(Double,Double){
let s = width * height
let c = (width + height) * 2
return (s,c)
}
print(area(3.1, height: 3.4))
函数使用
函数作为变量
func addTwoInts(a:Int,b:Int)->Int{
return a+b
}
func multiplyTwoInts(a:Int,b:Int)->Int{
return a*b
}
var mathFunction:(Int,Int) -> Int = multiplyTwoInts
print("Result:\(mathFunction(2,3))")
函数作为参数
func addTwoInts(a:Int,b:Int)->Int{
return a+b
}
func multiplyTwoInts(a:Int,b:Int)->Int{
return a*b
}
func printMathResult(mathFunction:(Int,Int)->Int,a:Int,b:Int){
print("Result:\(mathFunction(a,b))")
}
printMathResult(addTwoInts,a: 3,b: 5)
函数类型作为返回值类型
func squre(num:Int) ->Int{
return num * num
}
func cube(num:Int) ->Int{
return num * num * num
}
func getMathFunc (jack: String)-> (Int)->Int {
switch (jack){
case "squre":
return squre
default:
return cube
}
}
var mathFunc = getMathFunc("other") // 返回的值是需要传入整数的函数
print(mathFunc(5)) //所以这里传入整数
函数重载
形参和返回值不一样的同名函数
//1.
func test(){
print("无参数的test()函数")
}
//2.
func test (msg: String){
print("重载的test()函数\(msg)")
}
//3.
func test(msg: String) -> String {
print("重载的test()函数\(msg),带返回值")
return "test"
}
//4 这不算重载, 仅有形参名一样是不行的
func test(message:String){
print("重载的test()函数\(message)")
}
//调用1
test()
//调用2
var result:Void = test("Jike")
//调用3
var result2: String = test("Welcome , Geek")
嵌套函数
函数体内部所定义的函数
func getMathFunc(jackliu: String) -> (Int) ->Int{
func squre (num:Int) -> Int{
return num * num
}
func cube (num:Int) ->Int{
return num * num * num
}
switch(jackliu){
case "squre":
return squre
default:
return cube
}
}
var mathFunc:(Int)->Int = getMathFunc ("squre")
var mathFunc = getMathFunc ("squre") // 这样写说明即使不写变量的类型,系统也会进行推断
print(mathFunc(4)) //outcome is 16
mathFunc = getMathFunc ("other")
print(mathFunc(4)) //outcome is 64
Closure
一段可以作为参数传递给函数的代码
{ (parameters) -> return type in
statements to execute
}
例子
var bids = [48.1, 75.4, 63.7, 52.4, 68.2]
var orderedBids = bids.sort( {(bid1: Double, bid2:Double) -> Bool in
return bid2 > bid1
})
print(orderedBids)
Closure的简写形式
Example - 原有形式
var soups = ["tomato", "hot and sour", "french onion", "vegetable"]
var alphabeticalSoups = soups.sort({(soup1: String, soup2: String) -> Bool in
return soup2 > soup1
})
Example - 简写 ($0,$1,$2….分别代表第几个参数)
var soups = ["tomato", "hot and sour", "french onion", "vegetable"]
var hello = soups.sort({
$1 > $0
})
闭包的应用
func getMathFunc(jackliu: String) -> (Int) ->Int{
switch(jackliu){
case "squre":
return { (num: Int) -> Int in
return num * num
}
default:
return { (num:Int) -> Int in
return num * num * num
}
}
}
var mathFunc = getMathFunc("squre")
print(mathFunc(5)) //outcome is 25
mathFunc = getMathFunc ("other")
print(mathFunc(5)) //outcome is 125
利用上下文推断类型
Swift可以推断闭包的形参类型和返回值类型
函数和闭包是统一的,函数和闭包都是引用类型,当赋值给变量时,不会复制,而是指向同一个闭包
省略形参类型,因为从左侧就可以推断了
var squre:(Int) -> Int = {(num) in return num * num}
print(squre(3)) //outcome is 9
因为可以推断,所以小括号也是可以省略的
var squre:(Int) -> Int = {num in return num * num}
print(squre(3)) //outcome is 9
如果闭包表达式只有一行代码,而且这行代码就是返回值,也可以省略return。通过$0,$1…来引用第一个,第二个参数
var squre:(Int) -> Int = {$0 * $0}
print(squre(3)) //out come is 9
var result: Int = { //这里的Int不是返回值类型,而是形参
var result = 1
for i in 1...$1{
result *= $0
}
return result
}(4,3)
print(result) //outcome is 64
捕获上下文中的变量或者常量
闭包(嵌套函数)可以访问或者修改其所在上下文中的变量或常量
func makeArr(ele:String) -> () -> [String]{
//创建一个不包含任何元素的数组
var arr: [String] = []
func addElement() ->[String]{
//向arr数组中添加一个元素
arr.append(ele)
return arr
}
return addElement
}