函数式用来完成特定任务的独立的代码块.咱们给一个函数起一个合适的名字,用来表示函数作什么,而且当函数须要执行时,这个名字会被"调用".面试
在Swift中,每一个函数都有一种类型,包括函数的参数值类型和返回值类型.咱们能够吧函数类型当作任何其余普通变量类型同样处理,这样就能够更简单地吧函数当作别的函数参数,也能够从其余函数中返回函数.函数的定义能够写在其余函数定义中,这样能够在嵌套函数范围内实现功能封装.swift
当咱们定义一个函数时,能够定义一盒或多个有名字的值,做为函数的输入(参数,parameters),也能够定义某种类型值做为函数执行结束的输出(返回类型,return type). 每一个函数有个函数名,用来描述函数执行的任务.要使用一个函数式骂咱们用函数名"调用",而且传入它匹配的输入值(实参,araguments).一个函数的实参必须与咱们函数参数表里的参数的顺序一致.如:数组
func sayHello(name: String) -> String {
let say = "hello,\(name)"
return say
}
print(sayHello(name: "kobe"))
out:
hello,kobe
复制代码
全部的这些信息汇总起来成为函数的定义,并一 func 做为前缀.指定函数返回类型时,用返回箭头 -> 后跟返回类型的名称的方式来表示. 该定义描述了作什么,它指望接受什么和执行结束时返回的结果是什么.这样的定义使得函数能够在别的地方以一种清晰的方式调用.bash
函数参数和返回值在swift中极为灵活.咱们能够定义任何类型的汉斯顿,包括从值带一个未名参数的简单函数到互砸的带有表达性参数数名和不一样参数选项的复杂函数闭包
函数能够有多个输入参数,写在圆括号中,㐈逗号分隔.如:函数
func getMoney(number: Int, number1: Int) -> Int {
return number1 - number1
}
print("result:\(getMoney(number: 2, number1: 1))")
out:
result:0
复制代码
函数能够没有参数,下面这个函数就是一个无参函数,当它被调用时,返回固定的String消息:网站
func sayHi() -> String {
return "hi, kebe"
}
print("sayHi:\(sayHi())")
out:
sayHi:hi, kebe
复制代码
函数能够没有返回值,下面试sayHello函数的另外一个版本,函数直接输出String,特不是返回他ui
func sayHello(name: String) {
print("hello,\(name)")
}
sayHello(name: "kobe")
out:
hello,kobe
复制代码
咱们能够用元组(tuple)类型让锁哥值做为一个复合值从函数中返回,如:spa
func getMinMax(array: [Int]) -> (min: Int, max: Int) {
var min = array[0], max = array[0]
for item in array {
if item < min {
min = item
}
if item > max {
max = item
}
}
return (min,max)
}
let values = getMinMax(array: [1,2,3])
print("min:\(values.min),max:\(values.max)")
out:
min:1,max:3
复制代码
返回多个值,咱们使用元组,而且添加可选类型,如:.net
func getMinMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty {
return nil
}
var min = array[0], max = array[0]
for item in array {
if item < min {
min = item
}
if item > max {
max = item
}
}
return (min,max)
}
let numbs = [Int]()
if let values = getMinMax(array: numbs) {
print("min:\(values.min),max:\(values.max)")
} else {
print("没有数据")
}
out:
没有数据
复制代码
函数的参数,通常有外部参数名称(咱们称为参数别名)和本地参数名称(咱们成为参数).外部参数名称(参数别名)用于更好地让函数调用者当即这一参数的意思,本地参数名称(参数)用于在函数体中被实际调用.
在调用函数时,给每一个参数命名是很是有用的,由于这些参数名能够支持各个实参的用途是什么. 若是咱们但愿函数的使用者在调用函数式提供参数名字,那么久须要给玫瑰参数除了局部参数名外再定义一个外部参数名. 外部参数名写在局部参数名以前,用空格分割,如:
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
return s1 + joiner + s2
}
print(join(string: "hello,", toString: "be", withJoiner: "ko"))
out:
hello,kobe
复制代码
咱们能够在函数体重为每一个参数定义默认值.当默认值被定义后,为调用这个函数时,若是没有参数值,则使用参数定义的默认值,如:
func isStudent(name username: String, age: Int = 20) -> Bool {
var result: Bool = false
if age < 30 {
result = true
}
if username == "kobe" {
result = true
}
print("\(username) \(result ? "是学生" : "不是学生")")
return result
}
isStudent(name: "kobe")
isStudent(name: "zhangsan",age: 30)
out:
kobe 是学生
zhangsan 不是学生
复制代码
一个可变参数"variadic parameter" 能够接受一个或多个值. 当函数调用时,咱们能够用可变参数来传入不正确数量参数.经过在变量类型候命加入"..."的方式来定义可变参数. 传入可变参数的值在函数体内定作这个类型的一个数组,了如,一个叫做numbers的Int...型可变参数,在函数体内能够当作一个叫做numbers的Int[]型的数组常量,以下面的例子:
func sums(numbers: Int...) -> String {
var sum: Int = 0
var min = numbers[0]
var max = numbers[0]
for value in numbers {
sum += value
if value > max {
max = value
}
if value < min {
min = value
}
}
return "总和为:\(sum),最大值为:\(max),最小值为:\(min)"
}
print(sums(numbers: 1,2,3,4,5))
out:
总和为:15,最大值为:5,最小值为:1
复制代码
函数参数默认是常量.视图在函数体制那个更改参数值将会致使编译错误.这意味着咱们不能错过地更改参数值.可是有时候,若是函数中有传入参数的变量值副本警示颇有用的.咱们能够经过制定一个或多个参数为变量参数,从而避免本身在函数中定义新的变量.变量参数不是常量,能够在函数中把它当作新的可修改副原本使用,经过在参数明前加关键字 var 来定义参数,如:
func addChange( originstring s1: String, addString s2: String) -> String {
var s3 = s1 // 转换成变量
s3 = "---" + s3
return s3 + s2
}
print("hi to \(addChange(originstring: "hi", addString: "hello"))")
out:
hi to ---hihello
复制代码
变量参数,如上所述,仅能在函数体内被更改.若是咱们想要一个函数能够修改参数的值,而且星耀在这些修改在函数调用结束后仍然存在,那么久应该吧这些参数定义为输入输出参数 "In-Out parameter". 定义一个输入-输出参数时,在参数定义前加"inout"关键字. 一个输入-输出参数有传入函数的值,这个值被函数修改,而后被传出函数替换原来的值.
注意,输入-输出参数不能有默认值,并且可变参数不能用inout表示,若是用"inout"标识一个参数,这个参数不能被var 或 let 标记. 以下面的例子:
// 这个函数式将a 和 b 的值互换
func swapTwoInts(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var a1 = 100
var b1 = 200
// 调用输出参数的值是哟昂加&符号到参数
swap(&a1, &b1)
print("a1:\(a1), b1:\(b1)")
out:
a1:200, b1:100
复制代码
每一个函数都有特定的函数类型,由函数的参数类型和返回类型组成.
在swift中,使用函数类型就像使用其余类型同样,如:
func add(a: Int, b: Int) -> Int {
return a + b
}
func multipy(a: Int, b: Int) -> Int {
return a * b
}
// 能够这样定义函数变量
var tmp1 = add
var tmp2: (Int, Int) -> Int = multipy
// 函数变量的使用
print("1 + 1 = \(tmp1(1,1))")
print("1 * 2 = \(tmp2(1,2))")
out:
1 + 1 = 2
1 * 2 = 2
复制代码
当把函数类型当作参数使用时,咱们能够将函数的一部分实行交给函数的调用者,如:
func showMulipy(a: Int, b: Int, mutipy: (Int, Int) -> Int) {
let result = multipy(a: a , b: b)
print("\(a) * \(b) = \(result)")
}
showMulipy(a: 1, b: 3, mutipy: multipy)
out:
1 * 3 = 3
复制代码
能够看出 "mutipy"是个闭包(其实,函数只是闭包的一种特殊形式)
咱们可使用函数类型做为另外一个函数的返回类型.咱们须要作的是在返回箭头 -> 后写一个完整的函数类型,如:
func addOne(number: Int) -> Int {
return number + 1
}
func minusOne(number: Int) -> Int {
return number - 1
}
func isAddOrMinus(result: Bool) -> (Int)-> Int {
return result ? addOne : minusOne
}
print("调用函数类型做为返回值:\(isAddOrMinus(result: (1 > 0))(10))")
out:
调用函数类型做为返回值:11
复制代码
继续将上面例子的扩展,咱们能够吧函数类型做为常量使用,如:
var num = 10
let fuc = isAddOrMinus(result: num > 11)
while num != 0 {
print("\(num)", "terminator: ")
num = fuc(num)
}
out:
10 terminator:
9 terminator:
8 terminator:
7 terminator:
6 terminator:
5 terminator:
4 terminator:
3 terminator:
2 terminator:
1 terminator:
复制代码
本节所见到的全部函数都常做为全局函数(global funcation), 他们定义在全局域中. 咱们也能够把函数定义在别的函数体重,称做为嵌套函数(nested functions). 在默认状况下,嵌套汉是对外界不可见的,可是能够被其封闭函数来调用.一个封闭函数也能够返回他的某一个嵌套函数,似的这个函数能够在其余域中被使用.如:
func getResult(result: Bool) -> (Int,Int) -> Int {
func raise(a: Int, b: Int) -> Int {
return a + b
}
func cut(a: Int, b: Int) -> Int {
return a - b
}
return result ? raise : cut
}
// 定义常量函数
let fun = getResult(result: true)
// 调用嵌套的函数类型
var result = fun(100, 50)
print("reuslt:\(result)")
out:
reuslt:150
复制代码
微博:顺扬sky
简书:顺扬sky
掘金:顺扬sky