swift 函数(函数定义、函数参数、函数类型、嵌套函数)

1,914 阅读5分钟

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

函数定义与调用

在swift中,函数定义使用关键字func,使用返回箭头->指向函数返回类型

//函数定义
func sayHI(name:String, age:Int) -> String {
    return "我是\(name),今年\(age)岁"
}

//函数调用
let str = sayHI(name: "lily", age: 12)  

函数参数和返回值(无参数无返回、有参数无返回值、无参数有返回值、有参数有返回值)

  • 无参数,无返回值(没有定义返回类型的函数会返回Void,它其实是一个空的元组,可以写成())
    func sayHI(){
        print("sayHI")
    }
    sayHI()
    
    log:
    sayHI
    
  • 有参数,无返回值
    func sayHI(name:String)  {
        print("hello " + name)
    }
    sayHI(name: "李雷")
    
    log:
    hello 李雷
    
  • 无参数,有返回值
    func sayHI() -> String {
        return "sayHI"
    }
    let str = sayHI() 
    
    log:
    sayH
    
  • 有参数,有返回值
    func sayHI(name:String, age:Int) -> String {
        return "我是\(name),今年\(age)岁"
    }
    let str = sayHI(name: "李雷", age: 12)
    
    log:
    我是李雷,今年12

函数参数标签和参数名称

  • 指定参数标签

    swift支持函数参数标签,这种模式被称为外部形参。如果参数指定了外部形参标签,那么调用的时候就必须显示的使用,参数名称前面编写形参标签,用空格分隔

    func sayHI(name nameStr:String, age ageValue:Int) -> String {
        return "我是\(nameStr),今年\(ageValue)岁"
    }
    
    sayHI(name: "李雷", age: 12)
    
  • 省略参数标签

    函数不需要参数的参数标签,那么用下划线(_)代替参数的参数标签

    func sayHI(_ nameStr:String, _ ageValue:Int) {
    print("我是\(nameStr),今年\(ageValue)岁")
    }
    
    sayHI("李雷", 12)
    
  • 省略参数标签与下划线(_)

    如果觉得每个参数都指定参数标签或用下划线(_)代替参数的参数标签比较繁琐,我们可以直接使用参数名称来代替参数的参数标签

    func sayHI(nameStr:String, ageValue:Int) {
        print("我是\(nameStr),今年\(ageValue)岁")
    }
    
    sayHI(nameStr: "李雷", ageValue: 12)
    
  • 默认参数值

    函数体中可以为参数设置默认值,当默认值被设置之后,调用函数时可以忽略这个参数。一般将设置默认参数的参数放在参数列表的末尾,将没有设置默认值的参数放在函数参数列表的前面

    func sayHI(name:String, age:Int = 12) {
        print("我是\(name),今年\(age)岁")
    }
    
    sayHI(name:"李雷")            //我是李雷,今年12岁
    sayHI(name:"李雷", age: 18)   //我是李雷,今年18岁
    
  • 可变参数

    • 一个可变参数可以接受零个或多个值
    • 函数调用时,函数参数可以传入多个
    • 在参数类型名称后面使用(...)来定义可变参数
    • 可变参数的传入值在函数体中以数组形式读取
    • 一个函数最多只能拥有一个可变参数
      func message(_ strs:String...) {
          var totalStr = ""
          for str in strs {
              totalStr += str
          }
          print(totalStr)
      }
      
      message("s","a","y","H","I")  //sayHI
      
  • 输入输出参数(in-out

    默认情况下,函数参数是常量。不能直接在函数内部改变参数的值,也就是说函数的参数默认是值类型的。在实际使用中,往往需要直接在函数内修改参数值,也就是说需要传递的是引用,而不是值,这时我们把这个参数定义为in-out

    • in-out参数可以改变函数体外的值

    • 定义in-out参数时,在参数定义前加 in-out关键字

    • 只能将变量作为in-out参数的参数值进行传递,不能传递常量或文字值作为参数,因为不能修改常量和文字

    • 当传入的参数作为in-out参数时,需要在参数名前加&,表示这个值可以被函数修改

      func exchangeValue(valueA:inout Int, valueB:inout Int){
          let value = valueA
          valueA = valueB
          valueB = value
      }
      
      var a = 3
      var b = 5
      exchangeValue(valueA: &a, valueB: &b)
      print("a = \(a), b = \(b)")
      
      log:
      a = 5, b = 3
      

函数类型

  • 函数类型

    每个函数都有一个特定的函数类型,由函数的参数类型和返回类型组成

    func add(_ a:Int, _ b:Int) -> Int {
        return a + b
    }
    

    这个函数的类型是: (Int, Int) -> Int
    可以理解为“这个函数类型有俩个Int型的参数并返回一个Int型的值”

    func sayHI(){
        print("sayHI")
    }
    

    这个函数的类型是:() -> (),
    可以理解为“这个函数类型没有参数,没有返回值,没有返回值的函数通常会返回void,相当于返回一个空元组”

  • 函数类型的使用

    定义一个类型为函数的常量或变量,并将适当的函数赋值给它

    func add(_ a:Int, _ b:Int) -> Int {
        return a + b
    }
    
    var function :(Int,Int)-> Int = add
    print(function(2,3))
    

    定义一个叫做 function 的变量,类型是“一个有两个 Int 型的参数并返回一个 Int 型的值的函数”,并让这个新变量指向 add 函数

    • 函数类型作为参数

      定义了 showResult(_:_:_:) 函数,它有三个参数:第一个参数叫fun,类型是 (Int, Int) -> Int,你可以传入任何这种类型的函数;第二个和第三个参数分别是ab,它们的类型都是 Int,这两个值作为已给出的函数的输入值

      func showResult(_ fun:(Int,Int)->Int,_ a:Int,_ b:Int) {
          print(fun(a,b))
      }
      
      func add(_ a:Int, _ b:Int) -> Int {
          return a + b
      }
      
      showResult(add(_:_:), 3, 2)
      

      showResult(_:_:_:) 函数的作用就是输出另一个适当类型的数学函数的调用结果。它不关心传入函数是如何实现的,只关心传入的函数是不是一个正确的类型。这使得 showResult(_:_:_:) 能以一种类型安全(type-safe)的方式将一部分功能转给调用者实现。

    • 函数类型作为返回值

      定义了两个简单函数,分别是 sayHI(_:)sayHello(_:),这两个函数的类型都是 (String) -> String。之后在定义一个 showResult(:) 的函数,它的返回类型是 (String) -> String 类型的函数。showResult(backward:) 根据布尔值来返回 (String) -> String 类型函数

      func sayHI(_ name:String) -> String {
          return "HI \(name)"
      }
      func sayHello(_ name:String) -> String {
          return "Hello \(name)"
      }
      func showResult(_ backward: Bool) -> (String) -> String {
          return backward ? sayHI : sayHello
      }
      
      let show = showResult(true)
      print(show("world"))
        
      log:
      HI world
      

嵌套函数

嵌套函数:把函数定义在别的函数中

func showResult(_ backward: Bool) -> (String) -> String {
    func sayHI(_ name:String) -> String {
        return "HI \(name)"
    }
    func sayHello(_ name:String) -> String {
        return "Hello \(name)"
    }
    return backward ? sayHI : sayHello
}
 let show = showResult(true)
 print(show("world"))    //HI world