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 作为前缀.指定函数返回类型时,用返回箭头 -> 后跟返回类型的名称的方式来表示. 该定义描述了做什么,它期望接受什么和执行结束时返回的结果是什么.这样的定义使得函数可以在别的地方以一种清晰的方式调用.
二,函数的参数和返回值
函数参数和返回值在swift中极为灵活.我们可以定义任何类型的汉斯顿,包括从值带一个未名参数的简单函数到互砸的带有表达性参数数名和不同参数选项的复杂函数
2.1,多个输入参数的函数
函数可以有多个输入参数,写在圆括号中,㐈逗号分隔.如:
func getMoney(number: Int, number1: Int) -> Int {
return number1 - number1
}
print("result:\(getMoney(number: 2, number1: 1))")
out:
result:0
2.2 没有参数的函数
函数可以没有参数,下面这个函数就是一个无参函数,当它被调用时,返回固定的String消息:
func sayHi() -> String {
return "hi, kebe"
}
print("sayHi:\(sayHi())")
out:
sayHi:hi, kebe
2.3, 没有返回值的函数
函数可以没有返回值,下面试sayHello函数的另一个版本,函数直接输出String,特不是返回他
func sayHello(name: String) {
print("hello,\(name)")
}
sayHello(name: "kobe")
out:
hello,kobe
2.4, 多个返回值函数
我们可以用元组(tuple)类型让锁哥值作为一个复合值从函数中返回,如:
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
2.5, 元组可选类型返回值的函数
返回多个值,我们使用元组,并且添加可选类型,如:
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:
没有数据
三,函数的参数名称
函数的参数,一般有外部参数名称(我们称为参数别名)和本地参数名称(我们成为参数).外部参数名称(参数别名)用于更好地让函数调用者立即这一参数的意思,本地参数名称(参数)用于在函数体中被实际调用.
3.1 外部参数名称
在调用函数时,给每个参数命名是非常有用的,因为这些参数名可以支持各个实参的用途是什么. 如果我们希望函数的使用者在调用函数式提供参数名字,那么久需要给玫瑰参数除了局部参数名外再定义一个外部参数名. 外部参数名写在局部参数名之前,用空格分割,如:
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
3.2, 带默认值参数函数
我们可以在函数体重为每个参数定义默认值.当默认值被定义后,为调用这个函数时,如果没有参数值,则使用参数定义的默认值,如:
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 不是学生
3.3, 可变参数的函数
一个可变参数"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
3.4,常量参数和变量参数
函数参数默认是常量.视图在函数体制那个更改参数值将会导致编译错误.这意味着我们不能错过地更改参数值.但是有时候,如果函数中有传入参数的变量值副本警示很有用的.我们可以通过制定一个或多个参数为变量参数,从而避免自己在函数中定义新的变量.变量参数不是常量,可以在函数中把它当做新的可修改副本来使用,通过在参数明前加关键字 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
3.5,输入和输出参数
变量参数,如上所述,仅能在函数体内被更改.如果我们想要一个函数可以修改参数的值,并且星耀在这些修改在函数调用结束后仍然存在,那么久应该吧这些参数定义为输入输出参数 "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
四, 函数类型
每个函数都有特定的函数类型,由函数的参数类型和返回类型组成.
4.1, 使用函数类型
在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
4.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"是个闭包(其实,函数只是闭包的一种特殊形式)
4.3,使用函数类型作为返回值
我们可以使用函数类型作为另一个函数的返回类型.我们需要做的是在返回箭头 -> 后写一个完整的函数类型,如:
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
4.4, 使用函数类型作为常量
继续将上面例子的扩展,我们可以吧函数类型作为常量使用,如:
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:
4.5, 嵌套函数
本节所见到的所有函数都常作为全局函数(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
hi 各位大佬,如果您喜欢我的文章,可以在以下平台关注我
微博:顺扬sky
简书:顺扬sky
掘金:顺扬sky