This is the 7th day of my participation in Gwen Challenge

Function definition and invocation

In Swift, the function definition uses the keyword func, using the return arrow -> to point to the function return type

// Function definition
func sayHI(name:String.age:Int) -> String {
    return "I am \(name), this year \(age) year"
}

// Function call
let str = sayHI(name: "lily".age: 12)  
Copy the code

Function parameters and return values (no parameter no return, Yes parameter no return value, No parameter Return value, Yes parameter Return value)

  • No arguments, no return value (functions with no return type are returnedVoid, which is actually an empty tuple, can be written as(a))
    func sayHI(){
        print("sayHI")
    }
    sayHI()
    
    log:
    sayHI
    Copy the code
  • Argument, no return value
    func sayHI(name:String)  {
        print("hello " + name)
    }
    sayHI(name: "Li lei")
    
    log: hello, li leiCopy the code
  • No argument, return value
    func sayHI() -> String {
        return "sayHI"
    }
    let str = sayHI() 
    
    log:
    sayH
    Copy the code
  • There are parameters, there are return values
    func sayHI(name:String.age:Int) -> String {
        return "I am \(name), this year \(age) year"
    }
    let str = sayHI(name: "Li lei".age: 12)
    
    log: I'm Li Lei, this year12At the age ofCopy the code

Function parameter label and parameter name

  • Specify parameter label

    Swift supports function parameter labels, which are called external parameters. If the parameter specifies an external parameter label, then the call must display the use of the parameter label, separated by a space before the parameter name

    func sayHI(name nameStr:String, age ageValue:Int) -> String {
        return "I am \(nameStr), this year \(ageValue) years old"
    }
    
    sayHI(name: "Li lei".age: 12)
    Copy the code
  • Omit parameter label

    Function does not need argument labels, so use underscore (_) instead of argument labels

    func sayHI(_ nameStr:String, _ ageValue:Int) {
    print("I am \(nameStr), this year \(ageValue) years old")
    }
    
    sayHI("Li lei".12)
    Copy the code
  • Omit parameter label and underscore (_)

    If specifying a parameter label for each parameter or replacing the parameter label with an underscore (_) is too cumbersome, we can simply use the parameter name instead of the parameter label

    func sayHI(nameStr:String, ageValue:Int) {
        print("I am \(nameStr), this year \(ageValue) years old")
    }
    
    sayHI(nameStr: "Li lei".ageValue: 12)
    Copy the code
  • Default Parameter Value

    Default values can be set for parameters in the function body, and when the default values are set, the parameter can be ignored when the function is called. Arguments with default values are generally placed at the end of the argument list, and arguments without default values are placed at the front of the function argument list

    func sayHI(name:String, age:Int = 12) {
        print("I am \(name), this year \(age) year")
    }
    
    sayHI(name:"Li lei")            // MY name is Li Lei and I am 12 years old
    sayHI(name:"Li lei".age: 18)   // MY name is Li Lei and I am 18 years old
    Copy the code
  • Variable parameter

    • A variable parameter can accept zero or more values
    • When a function is called, more than one function parameter can be passed in
    • After the parameter type name, use (.) to define mutable parameters
    • The passed value of a variable argument is read as an array in the function body
    • A function can have at most one variable argument
      func message(_ strs:String.) {
          var totalStr = ""
          for str in strs {
              totalStr += str
          }
          print(totalStr)
      }
      
      message("s"."a"."y"."H"."I")  //sayHI
      Copy the code
  • Input/output parameters (in-out)

    By default, function arguments are constant. You cannot change the value of an argument directly inside a function, which means that function arguments are of value type by default. In practice, we define the parameter as in-out when we need to modify the parameter value directly within the function, that is, passing a reference rather than a value.

    • An in-out parameter can change the value outside the function

    • When defining an in-out parameter, add the in-out keyword before the parameter definition

    • You can only pass variables as parameter values for in-out parameters, not constants or literal values as parameters, because constants and literals cannot be modified

    • When a parameter is passed as an in-out parameter, the parameter name must be preceded by an ampersand to indicate that the value can be modified by the function

      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
      Copy the code

Function types

  • Function types

    Each function has a specific function type, consisting of the parameter type and return type of the function

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

    This function takes two arguments of type Int and returns a value of type Int.

    func sayHI(){
        print("sayHI")}Copy the code

    This function has no arguments and returns no value. Functions that do not return a value usually return void, which returns an empty tuple.

  • The use of function types

    Define a constant or variable of type function and assign the appropriate function to it

    func add(_ a:Int, _ b:Int) -> Int {
        return a + b
    }
    
    var function: (Int,Int) - >Int = add
    print(function(2.3))
    Copy the code

    Define a variable called function of type “a function that takes two ints and returns a value of Int”, and make the new variable point to the add function

    • Function type as argument

      ShowResult (_:_:_:), which takes three arguments: The first argument is called fun and is of type (Int, Int) -> Int. You can pass in any function of that type; The second and third arguments, a and b, are of type Int, and serve as input values to the given function

      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)
      Copy the code

      The showResult(_:_:_:) function simply prints the result of a call to another mathematical function of the appropriate type. It does not care how the passed function is implemented, only whether the passed function is of the correct type. This allows showResult(_:_:_:) to transfer some functionality to the caller implementation in a type-safe manner.

    • Function type as return value

      We define two simple functions, sayHI(_:) and sayHello(_:), both of type (String) -> String. We then define a showResult(:) function whose return type is (String) -> String. ShowResult (backward:) returns a (String) -> String function based on a Boolean value

      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
      Copy the code

Nested function

Nested functions: Define functions in other functions

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
Copy the code