Functions and Lambda Expressions (I)

Keywords: Java Programming

Introduction to function

Definition and invocation of functions

The grammar for defining functions is as follows:

fun function name (parameter list): return value type{
/ / function body
}

kotlin declares that functions must use fun keywords

The return value of a function can be any data type allowed by kotlin. How to declare the return value type of a function, the body of the function must have a valid return statement, which returns a variable or expression. If there is no return value, there are two declarations as follows:

  1. Omit the section ": return value type"
  2. Use ": Unit" to specify that returning Unit represents no return value, equivalent to void in java

The parameter list of a function is used to define the acceptable parameters of the function. The parameter list is composed of several groups of "parameter names: parameter types", separated by commas.

fun max(x: Int, y: Int): Int {
    val z = if (x > y) x else y
    return z
}

fun sayHi(name: String): String {
    return "${name} ,Hello!"
}

fun foo() {
    println("implement foo()function")
}

fun sayHello(name: String): Unit {
    print("${name},hello!")

}

fun main(args: Array<String>) {
    var a = 6
    var b = 9
    println("The maximum value is: ${max(a, b)}")

    print(sayHi("xq"))

    foo()

    sayHello("sq")
}

Recursive function

Calling itself in a function body is called function recursion.

//Recursive function
fun fn(n: Int): Int {
    when (n) {
        0 -> return 1
        1 -> return 4
        else -> return 2 * fn(n - 1) + fn(n - 2)
    }
}

fun main(args: Array<String>) {

    println("fn(10)The result is ${fn(10)}")

}

Single expression function

In some cases, a function returns only a single expression, in which case curly braces can be omitted and the body of the function can be specified after the equals sign, which is called a single expression function. For a single expression function, the compiler can derive the type of return value of the function, so it can omit writing.

//Single expression function
fun area(x: Double, y: Double): Double = x + y

fun product(x: Double, y: Double) = x * y

fun main(args: Array<String>) {

    println("1.2 + 2.5 = ${area(1.2, 2.5)}")
    println("1.2 * 2.5 = ${product(1.2, 2.5)}")
}

Formal parameters of functions

Named parameter

The parameter name of the kotlin function is not meaningless. Kotlin allows the parameter value to be passed in by name when calling the function.
Note that when you mix named parameters and location parameters when calling functions, the named parameters must be behind the location parameters.

//Formal parameters of functions
//Naming function
fun girth(width: Double, height: Double): Double {
    println("width: ${width},height: ${height}")
    return 2 * (width + height)
}
fun main(args: Array<String>) {
    //The traditional way to call a function is to pass in parameters according to location.
    girth(3.5, 4.9)
    //Pass in parameters by parameter name
    girth(width = 3.5, height = 4.9)
    //Using named parameters is a commutative location
    girth(height = 4.9, width = 3.5)
    //Some use named parameters, while others mix location parameters. Named parameters must be placed after location parameters.
    girth(3.5, height = 4.9)
}

Default values of parameters

In some cases, the program needs to specify a default value for one or more parameters when defining a function, so that when calling a function, the parameter can be omitted and the default value can be used directly. The syntax for specifying default values for parameters is as follows:

Parametric Name: Parametric Type = Default Value

If you define a function with parameters with default values in front of ordinary parameters and do not want to re-pass parameter values for default parameters, you can only use named parameters to pass parameter values for other parameters. So this is not recommended.

//Default values of parameters
fun sayHi(name: String = "xq", msg: String = "welcome") {
    println("name: $name ,msg: $msg")
}

fun printTriangle(height: Int = 5, char: Char) {
    for (i in 1..height) {
        for (j in 0 until height - 1) {
            print(" ")
        }

        for (j in 0 until 2 * i - 1) {
            print(char)
        }
        println()
    }

}
fun main(args: Array<String>) {
    //Use all default values
    sayHi()
    //Only msg uses default values
    sayHi("xy")
    //Neither of them uses default values
    sayHi("sqq", "hi")
    //Only name uses default values
    sayHi(msg = "Hello")

    printTriangle(6, '@')
    printTriangle(7, char = '#')
    printTriangle(char = '*')
}

Tail recursive function

kotlin also supports a tail recursive function programming approach, which can be used when the function calls itself as the last line of code it executes and there is no more code after the recursive call. In addition, tail recursion can no longer be used in try, catch, final, tail recursion needs to be modified with tailrec.

//Tail recursive function
fun fact(n: Int): Int {
    return when (n) {
        1 -> 1
        else -> n * fact(n - 1)
    }
}
tailrec fun factRec(n: Int, total: Int = 1): Int =
//if (n == 1) total else factRec(n - 1, total * n)
        when (n) {
            1 -> total
            else -> factRec(n - 1, total * n)
        }

fun main(args: Array<String>) {
    println("fact(10): ${fact(10)}")
    println("factRec(10):${factRec(10)}")
}

Variable number of parameters

kotlin allows the definition of variable number of parameters, so as to specify an uncertain number of parameters for the function. If vararg modification is added before the type of parameters when defining the function, it shows that the parameter can accept multiple parameter values and multiple parameter values are passed in as arrays.

kotlin allows a variable number of parameters to be anywhere in the parameter list, but requires a function to have at most one variable number of parameters, if the variable number of parameters is at the first of the parameter list, so the named parameters must be used when assigning the following parameters.

//Variable number of parameters
fun test(a: Int, vararg books: String) {
    for (b in books) {
        println(b)
    }
    println(a)
}
fun main(args: Array<String>) {
    test(2, "java", "kotlin")
}

function overloading

kotlin allows you to define multiple functions with the same name, as long as their list of parameters or return value types are different. If the program contains two or more functions with the same name, but only functions with different parameter lists, it will be overloaded.

fun test(a: Int, vararg books: String) {
    for (b in books) {
        println(b)
    }
    println(a)
}

//Function overloading
fun test() {
    println("The overload of a function, with a parameter function on it")
}

fun main(args: Array<String>) {
    test(2, "java", "kotlin")
    test()
}

Local function

The functions we have seen before are all defined globally. They are all global functions. kotlin also supports the definition of functions inside functions, which are called local functions.

By default, local functions are hidden from the outside. Local functions can only be valid in their closed functions, and their closed functions can also return local functions, so that the program can use local functions in other scopes.

//Local function
fun mathFunc(type: String, nn: Int): Int {
    fun square(n: Int): Int {
        return n * n
    }

    fun cube(n: Int): Int {
        return n * n * n
    }

    when (type) {
        "square" -> return square(nn)
        "cube" -> return cube(nn)
        else -> return 0
    }
}



fun main(args: Array<String>) {
    println(mathFunc("square", 3))
}

Posted by nodster on Sat, 11 May 2019 12:08:31 -0700