Characteristics of Unit function
- It is similar to void in java, but java is a key frame, not a type, which is very contradictory
- Unit is not written. It also exists by default. Unit represents the ignored type returned without parameters
package com.fyx.s1 fun main() { } fun convert() { } //Equivalent to the above fun convert1() : Unit{ }
The role of backquotes
- You can use Chinese characters or numbers to name functions or functions that name some keywords
package com.fyx.s1 fun main() { `This is a Chinese function name`() } //Function naming fun `This is a Chinese function name`() { } //Is is a keyword in kotlin. It cannot be a function, but it can be replaced by backquotes fun `is`() { println("ceshi") }
lambda expressions
- The {} after count is the lambda expression to filter out unqualified values
package com.fyx.s1 fun main() { //{} will traverse each character to filter the value of the composite parameter var datas = "Jeecg".count { it == 'e' } println(datas) }
Function variable declaration and implicit return
package com.fyx.s1 fun main() { //Variable declaration function var testFuncation: () -> String //Function implementation testFuncation = { var count = 100 //Implicit return means that you don't need to write return. The last line returns by default count.toString() } println(testFuncation()) }
Function variable argument declaration
package com.fyx.s1 fun main() { var testfunc: (Int, Int, Int) -> String = { num1, num2, num3 -> var prifix = "Digital set $num1 +number $num2 + number $num3"; prifix } println(testfunc(1,2,3)) }
The role of it and invoke
- it can be used when the function has only one parameter
- invoke equivalence and direct use of function fun1(1,2,3)
package com.fyx.s1 fun main() { var fun1: (Int, Int, Int) -> String = { n1, n2, n3 -> var name = "1234" "This is the number $n1 $n2 $n3 " } println(fun1.invoke(1, 2, 3)) var fun2: (String) -> String = { "This is the number $it " } println(fun2.invoke("12")) }
Type inference of anonymous functions
- Method name: return type must be specified
- Method name = data type can be automatically inferred according to the last row
package com.fyx.s1 fun main() { var fun1 = { var name = "1234" "This is a string" } }
Anonymous function lambda expression and return type Any
package com.fyx.s1 fun main() { //=lambda writing method of anonymous function var fun1 = { age1: Int, age2: Int -> "$age1 $age2" } println(fun1(12, 12)) //Any type because it is uncertain whether the last line returns a number or a string var fun2 = { age: Int -> when (age) { in 10..20 -> "Like flowers" else -> -1 } } println(fun2.invoke(21)) }
Trailing closure
- If the last argument of the function is a function type, if you intend to pass in a lambda expression as an argument, you are allowed to specify the lambda expression outside the parentheses
package com.fyx.s1 fun main() { //Define function var loginResult = { mes: String, code: Int -> println("Login results $mes Status code $code") } login("root", "1234", loginResult) } const val USER_NAME = "root" const val PASS_WORD = "1234" //Define a login method fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) { if (username == USER_NAME && Passowrd == PASS_WORD) { loginResult("Login succeeded", 200) } else { loginResult("Login failed", -200) } }
inline
- If the function parameter has lambda, try to use inline key frames, which will be optimized internally to reduce the loss of function development and object development
package com.fyx.s1 fun main() { //Define function var loginResult = { mes: String, code: Int -> println("Login results $mes Status code $code") } login("root", "1234", loginResult) } const val USER_NAME = "root" const val PASS_WORD = "1234" //Define a login method inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) { if (username == USER_NAME && Passowrd == PASS_WORD) { loginResult("Login succeeded", 200) } else { loginResult("Login failed", -200) } }
Precautions for inlining
-
Since the JVM can intelligently judge whether to inline optimize ordinary functions according to the actual situation, we do not need to use Kotlin's inline syntax, which will only make the bytecode more complex.
-
Try to avoid inlining functions with a large number of function bodies, which will lead to too many bytecodes.
-
Once a function is defined as an inline function, you cannot get the private members of the closure class unless you declare them internal.
Function to function object
- Here we find that the direct reference function reports an error because it is a function type object. How to convert a function into a function object? We can use::
package com.fyx.s1 const val USER_NAME = "root" const val PASS_WORD = "1234" fun main() { login("root", "1234", ::loginResult) } //Function type fun loginResult(mes: String, code: Int): Unit { println("Login results $mes Status code $code") } //Define a login method inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) { if (username == USER_NAME && Passowrd == PASS_WORD) { loginResult("Login succeeded", 200) } else { loginResult("Login failed", -200) } }
Return function parameters
package com.fyx.s1 fun main() { var method2 = method1("details") println(method2.invoke("trouble", 18)) } fun method1(info: String): (String, Int) -> String { println(info) return { name: String, age: Int -> "$name $age " } }
Anonymous and named functions
- Anonymous functions are declared inside methods
package com.fyx.s1 const val USER_NAME = "root" const val PASS_WORD = "1234" fun main() { login("root", "1234", { name, age -> println("$name + $age ") }) } inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) { if (username == USER_NAME && Passowrd == PASS_WORD) { loginResult("Login succeeded", 200) } else { loginResult("Login failed", -200) } }
- A named function converts a function into an object function through:: function
package com.fyx.s1 const val USER_NAME = "root" const val PASS_WORD = "1234" fun main() { login("root", "1234",::loginResult) } fun loginResult(mes: String, code: Int): Unit { println("Login results $mes Status code $code") } inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) { if (username == USER_NAME && Passowrd == PASS_WORD) { loginResult("Login succeeded", 200) } else { loginResult("Login failed", -200) } }
Nullability of Kotlin
- Many null pointer exceptions can be encountered in traditional java projects, but not in kotlin projects
package com.fyx.s1 fun main() { //We found that the parameter cannot be set to nullable var name = "test" name = null //Can you add one if necessary? Setting this variable can be assigned to null var names: String? names=null }
Safe call operator
- If the variable is set to be nullable, remedial measures are required for all operation functions of the variable, that is, when it is empty, it will not be executed
- The way to use this method is to add "yes" at the end of the variable when calling the function?
package com.fyx.s1 fun main() { var name:String? ="Model" name?.capitalize() }
let security call
- When the value is empty, you cannot enter the function of let, and you can perform security verification on variables
package com.fyx.s1 fun main() { var name: String? = null name?.let { println("Not empty") } }
!! predicated operations
- This means that if the name is empty, the next step will be carried out. If it is empty, the package null pointer will be abnormal
package com.fyx.s1 fun main() { var name: String? = null name!!.toBigDecimal(); }