Kotlin Learning Note (ix) function, lambda expression

Source: Internet
Author: User
Tags anonymous

function

Kotlin, a function is defined using the Fun keyword, and the function parameter is defined by the Pascal notation, which is name:type. Parameters are separated by commas. Each parameter must have an explicit type.

Fun foo (arg1:string,arg2:boolean,arg3:int): int{
    //do somethong
    return 1
}

When a function has only a single expression, you can omit the curly braces, write directly after =, or omit the return value type if the return value type can be inferred by the compiler:

Fun foo (arg1:string,arg2:boolean,arg3:int) =1//the function form after omitting curly braces and returning value types

A function that has a block code body must explicitly specify a return value type unless the return value type is unit. The compiler does not infer the return type of a function that has a block code body, because such a function may have complex control flows in the code body, and the return type is not obvious to the reader (and even the compiler).

Fun foo (arg1:string,arg2:boolean,arg3:int): int{
    print ("arg1=" +arg1+ "&arg2=" +arg2+ "arg3=" +arg3)
    return 0
}

Calling a function using the traditional method

var Value=foo ()

Call of member function to use dot notation

R (). Foo ()

Functions can also be invoked using infix notation, when a condition is met:

Infix fun Int.add (x:int): int{
    return this+x
} fun

Printadd () {
    val value=2 add 3//infix notation Call the Add function
    Print ("The value is $value")
}

We can also use named arguments when calling a function:

Fun foo (arg1:string= "Hello Kotlin", arg2:boolean,arg3:int) {
    print ("arg1=" +arg1+ "&arg2=" +arg2+ "arg3=" +arg3 )
} fun

Printfoo () {
    foo (arg2 = TRUE,ARG3 = 7)//Name parameter call foo function
}

A function parameter can have a default value, and the default value is used when the corresponding argument is omitted. This can reduce the number of overloads compared to other languages.

Fun Foo3 (arg1:string,arg2:boolean=false,arg3:int=0) {//default parameter to be placed on the last side of the function parameter
    print ("arg1=" +arg1+ "&arg2=" +arg2 + "arg3=" +arg3)
} fun

PrintFoo3 () {
    Foo3 ("Hello Kotlin")//call, you can not pass in the value of the default parameter, the default parameter will use the default value
}

We can also define a variable number of parameters for the function, as long as the VARARG keyword is modified:

Variable number of parameters fun
Foo4 (vararg args:int) {
    for (arg in args) {
        print (arg.tostring () + ",")
    }
}

PrintFoo4 () {
    Foo4 (1,2,3,4,5)//1,2,3,4,5,
}

If we already have an array and want to pass its contents to the function, we use the stretch (spread) operator (preceded by the array *):

Variable number of parameters fun
Foo4 (vararg args:int) {
    for (arg in args) {
        print (arg.tostring () + ",")
    }
}

Fun PrintFoo4 () {
    val values= intarrayof (1,2,3,4,5)
    Foo4 (*values)//Use an extension operator to pass an array to a mutable argument
}

Higher order functions

Higher-order functions can use a function as a parameter or a return value:

Fun Add2 (x:int=0,y:int=0): int{
    return x+y
} fun

operate (x:int=0,y:int=0,body: (int,int)->int) {// Body is a function type, passing in two int type parameters, returning an int type parameter
    print ("This result is" +body (x, y))
} fun

GetValue () {
    Operate (3,7,::ADD2)
}

lambda expression

The operate () method above, we also have a more concise way to call, that is, to pass in a lambda expression:

Fun GetValue () {
    operate (3,7,::ADD2)//function parameter passed in a function
    operate (3,7,{x,y->x+y})//function parameter passed in a lambda expression
}

The full syntactic form of a LAMBDA expression, that is, the literal value of the function type is as follows:

Val sum = {x:int, y:int x + y}

The lambda expression is always enclosed in curly braces, with the full syntax of the argument declared in parentheses, with an optional type callout and the function body followed by a symbol. If the inferred return type of the lambda is not a Unit, then the last (or possibly a single) expression in the lambda body is treated as a return value.

If we leave all the optional annotations, it looks like this:

Val sum: (int, int), int = {x, y, x + y}

When the function argument is the last parameter of the last function, and you pass in a lambda expression as the corresponding parameter, you can specify it outside the parentheses:

Fun GetValue () {
    operate (3,7,::ADD2)//function parameter passed in a function
    operate (3,7,{x,y->x+y})//function parameter passed in a lambda expression
    Operate (3,7) {//function parameter as the last parameter of the function, and passed in a lambda expression, can be specified outside the parentheses
        x,y->x+y
    }
}

If the lambda expression has only one parameter, Kotlin can calculate the signature on its own, which allows us not to declare a unique parameter, and implicitly declares its name as it:

Fun UpCase (str:string,body: (String)->string): String{//body is a function parameter, passing in a string type parameter, returning a string type return
    body (str)
}
Fun transform () {
    upCase ("Hellokotlin") {//functor have only one parameter, you can omit the parameter declaration, which is the IT
        it.touppercase ()
    }
}

If the lambda expression is the only argument that is called, the parentheses in the call can be completely omitted:

Fun String.upper (Body: (String)->string): string{
    return Body (this)
} fun

transform () {
    " Hellokotlin ". Upper {It.touppercase ()}//lambda is the only parameter called, the parentheses of the call can be omitted
}

Anonymous Functions

Anonymous functions, like regular functions, simply omit the function name:

Fun String.upper (Body: (String)->string): string{
    return Body (this)
} fun

transform () {
    " Hellokotlin ". Upper {it.touppercase ()}//lambda expression is the only argument that is called, the parentheses you call can omit
    " Hellokotlin ". Upper (Fun (str:string): string{//passing an anonymous function as a function parameter to
        return Str.touppercase ()
    })
}

Another difference between a lambda expression and an anonymous function is the behavior of a non-local return. A return statement without a label is always returned in a function declared with the FUN keyword. This means that return in the lambda expression will be returned from the function that contains it, and return in the anonymous function will be returned from the anonymous function itself.

Fun foo () {
    Ints.foreach {
        if (it = = 0) return//This return expression is returned from the function that most directly surrounds it-Foo.
        print (IT)
    }
}

It is important to note that this non-local return only supports lambda expressions passed to inline functions. If we need to return from a lambda expression, we must label it and use it to limit the return.

Fun transform (): string{
    "Hellokotlin". Upper {
        print (it.touppercase ())
        return@upper it.touppercase ()// Return must be tagged limit
    }
    "Hellokotlin". Upper (Fun (str:string): string{return
        str.touppercase ()//returned from anonymous function
    })
}

function literal with receiver

The Kotlin provides the ability to specify the number of receiver invocation function literals. In the function body of the function literal, you can call the method on the recipient object without any additional qualifiers.
The type of this function literal is a function type with a receiver:

Sum:int. (other:int), Int

The literal value of the function can be called as if it were a method on the receiver object:

1.sum (2)

The anonymous function syntax allows you to directly specify the recipient type of the function's literal value. This is useful if you need to declare a variable with a function type with a receiver and use it later.

Val sum = fun int. (other:int): Int. = this + other

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.