美文网首页Swift5.1语法学习
六、函数定义、用法以及函数注释

六、函数定义、用法以及函数注释

作者: 爱玩游戏的iOS菜鸟 | 来源:发表于2020-01-04 15:12 被阅读0次

    Swift函数

    Swift函数的定义
    1. 有返回值的函数
    //有返回值的函数
    //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))
    
    1. 无返回值的函数
    //无返回值的函数
    func fun() -> Void{
        print("hello")
    }
    
    func happy() ->(){
        print("hello")
    }
    
    func empty(){
        print("hello")
    }
    

    上面三种本质上是一样的
    ∵Void即为空元祖的别名 public typealias Void = ()

    1. 隐式返回的函数
    func single(v1:Int, v2:Int) -> Int{
        v1 + v2
    }//单一表达式,可省略reutrn
    
    1. 多返回值的函数(使用元组实现多值返回)
    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)
    
    函数参数标签和形参名
    1. 默认情况 形参使用形参名作为参数标签
    2. 指定参数标签
    3. 参数标签可选择性省略
    • 【区别】函数调用更加明确,可读性更高
    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")//省略参数标签
    
    函数默认参数值
    1. 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
    
    1. 如果省略标签就必须要注意
    func test(_ first:Int = 10, _ second:String, _ third:String = "Hello") {
        print(first,second,third)
    }
    
    test("Hello")//报错 无法正确赋值 因此second不可以省略标签
    test(10, "Hello", "World")
    
    可变参数
    1. 一个可变形式参数可以接受多个同类型的值,类型后面加(...
    //可变参数紧跟着的下一个函数标签不可省略
    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"))")
    

    【注意】
    一个函数只能有一个可变参数
    可变参数紧跟着的下一个函数标签不可省略

    1. 系统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)
    1. 函数名相同
    2. 参数个数不同 || 参数类型不同 || 参数标签不同
    • 【注意】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分别构成参数个数、类型、标签不同

    主要注意的是:
    1. 函数重载类型与返回值无关


      产生二义性
    2. 默认参数值与函数重载一起使用也会产生二义性,但是不报错(※但不推荐这样使用)

      不会产生二义性
    3. 可变参数、省略参数标签、函数重载一起使用可能会报错(※不推荐使用)


      ABC同时存在,会报错 关掉A,就不报错 所以很奇怪
    内联函数(Inline Function)

    如果开启了编译器的优化(Release模式默认开启优化)编译器会自动将某些函数编程内联函数(将函数展开成函数体)

    【注意】哪些函数不会被内联?

    • 函数体比较长
    • 递归调用
    • 动态派发
    将Debug调试模式开启优化

    @inline 指定函数不被内联或强制内联(了解一下就行,编译器自动优化就足够)


    @inline()
    函数类型
    1. 什么是函数类型?
    • 每一个函数都有一个特定的函数类型
    • 形参类型、返回类型组成
    func sum(v1 :Int,v2: Int) ->Int{
        v1 + v2
    }
    

    函数类型:(Int, Int)->Int
    读作:"有两个形参的函数类型,形参类型都是Int ,并且返回Int类型的值"

    1. 参数类型的使用
    • 定义变量调用函数
    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
    
    1. 函数类型作为函数返回值
    • 返回值是函数类型的函数 是高阶函数
    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)
    
    嵌套函数
    1. 看到目前为止 所有的函数都是在全局范围定义的 也可以在函数内部定义 即为嵌套函数
    2. 在外部看起来是隐藏的 但是可以通过包裹函数来间接调用
    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

    相关文章

      网友评论

        本文标题:六、函数定义、用法以及函数注释

        本文链接:https://www.haomeiwen.com/subject/rlwxactx.html