[Swift 4] (5) Function basically uses | variable parameter | inout reference transfer | function type return value | function nesting

Keywords: Mobile

Fundamental use of functions

Keyword: func
func hello(name:String) ->String
{
    let result =  "Hello,"+name
    return result
}
hello(name: "imagine")

Lectotype:

func hello(name:String?,greet:String) ->String
{
    let result =  greet+","+(name)!
    return result
}

var nickname:String?  //nil
nickname = "imagine"
hello(name: nickname,greet: "Good Night") //Good Night,imagine"

No parameter function, directly returns a function of string type:

func sayHello() ->String
{
    return "Welcome to imaginecode"
}
sayHello() //"Welcome to imaginecode"

Empty type void / (), does not return any value

func sayVoid() ->Void{
    print("it is a void func")
}

Use tuples to get functions to return multiple values

func maxminScores( scores:[Int]) -> ( maxscore:Int,minscore:Int)? //Optional types of tuples
{
    if scores.isEmpty{
        return nil
    }
    var curmax = scores[0] ,curmin = scores[0]
    for score in scores[1..<scores.count]{
        curmax = max(curmax, score)
        curmin = min(curmin, score)
    }
    return (curmax,curmin)
}
var scores:[Int]? = [12,60,71,81,91,100] //Optional array
scores = scores ?? []
if let result = maxminScores(scores: scores!)
{
    print(result.maxscore)
    print(result.minscore)
}

Internal and external parameter names

func hello(userName nickname:String,greeting greet:String) -> String{ //Internal parameters nickname,greet, belong to function body
    let result = greet+":"+nickname
    return result
}
hello(userName: "imagine", greeting: "codeing") //External parameter names userName and greet ing are given to the parameters nickname and green

Default values of parameters

func hello(nickname:String,greet:String = "hello") -> String{ //Give greet the default value hello
    let result = greet+":"+nickname
    return result
}
hello(nickname: "imagine") //"hello:imagine"
func hello(nickname:String,greet:String = "hello",other:String = "nihao") -> String{ //Give greet the default value hello
    let result = greet+":"+nickname+other
    return result
}
hello(nickname: "imagine",other:"how do you do") //"hello:imaginehow do you do"

Variable parameters

  • It's better for a function to have only one variable parameter, and that variable parameter can only be placed at the end of the function parameter list.
  • Must parameter > default parameter > variable parameter
func add(a:Int,b:Int,others:Int ... ) ->Int //Other is a variable parameter... parse it into an array
{
    var result = a + b
    for num in others
    {
        result += num
    }
    return result
}
var res = add(a: 2, b: 3)

res = add(a: 2, b: 3, others: 4,5,6)

NSLog(format: String, args: CVarArg...) //CvarArg is also a variable parameter

inout parameter - Reference passing

  • inout is used to declare that data is passed by address, also known as reference transfer.
  • The parameters modified by inout can not have default values, and the set of parameters with range can not be modified.
  • Once a parameter is modified by inout, it can no longer be modified by var and let.
func swapTwoInts( a:inout Int,b:inout Int)
{
    let t = a;
    a = b
    b = t
}
var x = 0, y = 100

swapTwoInts(a: &x, b: &y) //Input reference parameters

Function type

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

let anotherAdd:(Int,Int)->Int = add //The parameter is two Ints, the return type is Int, and add is a variable


anotherAdd(3,4)
func changeScores1(scores:inout [Int]) {
    for i in 0..<scores.count {
        scores[i] = Int(sqrt(Double(scores[i]))*10)
    }
}

func changeScores2(scores:inout [Int]) {
    for i in 0..<scores.count {
        scores[i] = Int(sqrt(Double(scores[i]))/150.0 * 100.0)
    }
}
func changeScores3(scores:inout [Int]) {
    for i in 0..<scores.count {
        scores[i] += 3
    }
}

var scores1 = [20,40,60,80,90]
changeScores1(scores: &scores1)

var scores2 = [20,40,60,80,90]
changeScores2(scores: &scores2)

var scores3 = [20,40,60,80,90]
changeScores3(scores: &scores3)

Improvement:

func changeScores(op:(Int)->Int, scores:inout [Int])
{
    for i  in 0..<scores.count{
        scores[i] = op(scores[i])
    }
}
func op1(x:Int)->Int {return Int(sqrt(Double(x))*10)}
func op2(x:Int)->Int {return Int(sqrt(Double(x))/150.0*100.0)}
func op3(x:Int)->Int {return x + 3}

var scores1 = [20,40,60,80,90]
changeScores(op: op1, scores: &scores1)

var scores2 = [20,40,60,80,90]
changeScores(op: op2, scores: &scores2)

var scores3 = [20,40,60,80,90]
changeScores(op: op3, scores: &scores3)
var arr = [Int]()

for _ in 1...20
{
    arr.append(Int(arc4random()%100))
}
arr

func compareTwoInts(a:Int,b:Int) -> Bool{return a>b }

arr.sort()

Return function type return value, function nesting

//Postage
func mailcost1(weight:Int) -> Int
{
    return 1*weight
}
func mailcost2(weight:Int) -> Int
{
    return 2*weight
}
func chooseMailCostMethod(weight:Int) -> (Int)->Int //Returns an Int-type function, decoupling
{
    return weight <= 10 ? mailcost1 : mailcost2
}

func totalCost(price:Int,weight:Int) -> Int
{
    let mailCost:(Int)->Int = chooseMailCostMethod(weight: weight)
    return mailCost(weight) + price*weight
}

Another way of writing: function nesting

func mailcost1(weight:Int) -> Int
{
    return 1*weight
}
func mailcost2(weight:Int) -> Int
{
    return 2*weight
}

func totalCost(price:Int,weight:Int) -> Int
{
    func chooseMailCostMethod(weight:Int) -> (Int)->Int //Function nesting
    {
        return weight <= 10 ? mailcost1 : mailcost2
    }
    
    let mailCost:(Int)->Int = chooseMailCostMethod(weight: weight)
    return mailCost(weight) + price*weight
}

Posted by Trojan on Fri, 01 Feb 2019 12:12:15 -0800