六、函数定义、用法以及函数注释
2020-01-04 本文已影响0人
爱玩游戏的iOS菜鸟
Swift函数
Swift函数的定义
- 有返回值的函数
//有返回值的函数
//func 函数名() -> 返回值类型{}
func pi() ->Double{
return 3.14
}
print(pi())
func sum(v1:Int, v2:Int) -> Int{
return v1+v2
}
print(sum(v1: 10, v2: 20))
- 无返回值的函数
//无返回值的函数
func fun() -> Void{
print("hello")
}
func happy() ->(){
print("hello")
}
func empty(){
print("hello")
}
上面三种本质上是一样的
∵Void即为空元祖的别名 public typealias Void = ()
- 隐式返回的函数
func single(v1:Int, v2:Int) -> Int{
v1 + v2
}//单一表达式,可省略reutrn
- 多返回值的函数(使用元组实现多值返回)
func caculate (v1:Int, v2:Int) -> (sum:Int, avg:Int, max:Int, min:Int){
let sum = v1 + v2
let max = v1 > v2 ? v1 :v2
let min = v1 < v2 ? v1 :v2
return (sum,sum / 2,max,min)
}
print(caculate(v1: 10, v2: 20))//输出:(sum: 30, avg: 15, max: 20, min: 10)
函数参数标签和形参名
- 默认情况 形参使用形参名作为参数标签
- 指定参数标签
- 参数标签可选择性省略
- 【区别】函数调用更加明确,可读性更高
func goToWork (time :String){
print("Work time is \(time)")
}
func goToNewWork (at time :String){//*推荐
print("New work time is \(time)")
}
func goToDeleteWork(_ time:String) {//省略参数标签
print("Delete work time is \(time)")
}
goToWork(time: "8:00 am")
goToNewWork(at: "8:00 am")//更清晰明白 推荐指定参数标签
goToDeleteWork("8:00 am")//省略参数标签
函数默认参数值
- C++中默认参数必须从右往左设置,∵swift有参数标签 ∴无此限制
func check(name:String = "NoBody", age:Int, job:String = "None"){
print("name = \(name), age = \(age), job = \(job)")
}
check(age: 15)//输出:name = NoBody, age = 15, job = None
check(name: "崔静恩", age: 20, job: "Android")//输出:name = 崔静恩, age = 20, job = Android
check(name: "季庭", age: 18)//输出:name = 季庭, age = 18, job = None
check(age: 17, job: "iOS")//输出:name = NoBody, age = 17, job = iOS
- 如果省略标签就必须要注意
func test(_ first:Int = 10, _ second:String, _ third:String = "Hello") {
print(first,second,third)
}
test("Hello")//报错 无法正确赋值 因此second不可以省略标签
test(10, "Hello", "World")
可变参数
- 一个可变形式参数可以接受多个同类型的值,类型后面加(...)
//可变参数紧跟着的下一个函数标签不可省略
func test(_ numbers:Int...,maxNumber:Int,_ other:String) -> String {
var total = 0
for number in numbers {
total += number
}
return total > maxNumber ? "total "+other : "maxNumber "+other
}
//输出:The max Value is maxNumber end
print("The max Value is \(test(10,20,30,40,50, maxNumber: 200, "end"))")
【注意】
一个函数只能有一个可变参数
可变参数紧跟着的下一个函数标签不可省略
-
系统print函数 就是带有一个可变参数,其余2个形参带有默认形参值的函数
系统print函数
输入输出参数(in-Out Parameter)
func swapValuesAnother(_ v1: inout Int , _ v2: inout Int) {
(v1,v2) = (v2,v1)
}
var value1 = 10
var value2 = 20
swapValuesAnother(&value1, &value2)//自定义交换值函数
print(value1,value2)//输出:20 10 交换一次
swap(&value1, &value2)//Swift定义好的
print(value1,value2)//输出:10 20 再交换一次
【注意】
1.可变参数不能标记为inout
2.inout不能有默认值
3.inout只能传入变量
4.inout本质是地址传递
5.inout只能传入可以被多次赋值的
6.&在C中为取地址符 在Swift中只能用在函数参数这里'
函数重载(Function OverLoad)
- 函数名相同
- 参数个数不同 || 参数类型不同 || 参数标签不同
- 【注意】2个条件必须同时符合标准
//A
func sum(v1 :Int,v2: Int) ->Int{
v1 + v2
}
//B
func sum(v1 :Int,v2: Int,v3: Int) ->Int{
v1 + v2 + v3
}//参数个数不同
//C
func sum(v1 :Int,v2: Double) ->Double{
Double(v1) + v2
}//参数类型不同
//D
func sum(_ v1 :Int,_ v2: Int) ->Int{
v1 + v2
}//省略标签 参数标签不同
//E
func sum(a:Int,b: Int) ->Int{
a + b
}//参数标签不同
sum(v1: 10, v2: 20)//A
sum(v1: 10, v2: 20, v3: 30)//B
sum(v1: 20, v2: 20.5)//C
sum(10, 20)//D
sum(a: 10, b: 20)//E
函数名都相同,A与B、A与C、A与D/E分别构成参数个数、类型、标签不同
主要注意的是:
-
函数重载类型与返回值无关
产生二义性 -
默认参数值与函数重载一起使用也会产生二义性,但是不报错(※但不推荐这样使用)
不会产生二义性
-
可变参数、省略参数标签、函数重载一起使用可能会报错(※不推荐使用)
ABC同时存在,会报错 关掉A,就不报错 所以很奇怪
内联函数(Inline Function)
如果开启了编译器的优化(Release模式默认开启优化)编译器会自动将某些函数编程内联函数(将函数展开成函数体)
【注意】哪些函数不会被内联?
- 函数体比较长
- 递归调用
- 动态派发
@inline 指定函数不被内联或强制内联(了解一下就行,编译器自动优化就足够)
@inline()
函数类型
- 什么是函数类型?
- 每一个函数都有一个特定的函数类型
- 由形参类型、返回类型组成
func sum(v1 :Int,v2: Int) ->Int{
v1 + v2
}
函数类型:(Int, Int)->Int
读作:"有两个形参的函数类型,形参类型都是Int ,并且返回Int类型的值"
- 参数类型的使用
- 定义变量调用函数
func sum(v1 :Int,v2: Int) ->Int{
v1 + v2
}
var funcSum :(Int,Int) -> Int = sum(v1:v2:)
funcSum(10,20)//输出:30 调用时不需要参数标签
- 函数类型作为函数参数
func sum(v1 :Int,v2: Int) ->Int{
v1 + v2
}
func difference(a:Int,b:Int) -> Int{
a - b
}
func result(_ mathFunc:(Int, Int) -> Int, _ a:Int, _ b: Int) -> Int {
mathFunc(a,b)
}
// sum / difference函数作为result函数的参数传入
print(result(sum(v1:v2:), 10, 20))//输出:30
print(result(difference(a:b:), 10, 20))//输出:-10
- 函数类型作为函数返回值
- 返回值是函数类型的函数 是高阶函数
func numAdd(_ a:Int) ->Int{
a+1
}
func numReduce(_ a:Int) ->Int{
a-1
}
func result(_ flag:Bool) -> (Int)->Int {
flag ? numAdd : numReduce
}
//根据结果返回numAdd函数还是numReduce函数
var mathFunc : (Int)->Int = result(true)
mathFunc(3)//输出:4
mathFunc = result(false)
mathFunc(4)//输出:3
类型别名 typealias定义类型别名
//Int类型别名
typealias ZzqInt = Int
let zqValue :ZzqInt = 10
var zqMin = ZzqInt.min
//元组类型别名
typealias zzqDate = (year:Int, month:Int, day:Int)
func returnDate(_ date:zzqDate){
print(date.0, date.1, date.2, separator: "-", terminator: "\n")
}
returnDate((2020,02,20))
//函数类型别名
func numReduce(_ a:Int) ->Int{
a-1
}
typealias aliasFunc = (Int) -> Int
let newFn : aliasFunc = numReduce
newFn(5)
//函数参数
func setFn(_ fn:aliasFunc){
fn(5)
}
setFn(numReduce)
//函数返回值
func getFn() -> aliasFunc{
numReduce
}
getFn()(5)
嵌套函数
- 看到目前为止 所有的函数都是在全局范围定义的 也可以在函数内部定义 即为嵌套函数
- 在外部看起来是隐藏的 但是可以通过包裹函数来间接调用
func result(_ flag:Bool) -> (Int)->Int {
func numAdd(_ a:Int) -> Int{
a + 1
}
func numReduce(_ a:Int) -> Int{
a - 1
}
return flag ? numAdd : numReduce
}
result(true)//(Int) -> Int
result(false)(5)
函数文档注释
以上面的函数为例显示结果
Swift学习日记6.0