This article is only for recording learning, so if there are some mistakes or wrong understanding, please correct.

Kotlin’s Study Notes (7)

Description:

  1. Function review and summary
  2. A review of named parameters
  3. Review of infix grammar

function

In the previous chapter, I summarized the use of functions along with the textbook, but it was not basic enough. Here, I will study it systematically again according to Kotlin’s Chinese website.

// Functions in Kotlin are declared using the fun keyword
fun double(x: Int): Int {
    return 2 * x
}
fun double1(x: Int = 0): Int {
    return 2 * x
}

fun main(args: Array<String>) {
    val result = double(2)}Copy the code

We basically know how to write some functions:

  1. Methods (functions) are declared using the fun keyword
  2. In this example, double is the name of the function
  3. Function parameters are defined using Pascal notation, namely name: type. Use commas (,) to separate parameters. Each parameter must have an explicit type.
  4. X: Int = 0 (function arguments can have default values, which are used when they are omitted. This reduces the number of overloads compared to other languages)

So let’s say a little bit more about the default

open class A {
    open fun foo(i: Int = 10){... }}class B : A() {
    override fun foo(i: Int) { …… }  // No default value
}
Copy the code

Override methods always use the same default parameter values as base type methods. When overriding a method with default parameter values, the default parameter values must be omitted from the signature.

1.1 Named Parameters

You can use named function arguments when the function is called. This is handy when a function has a large number of arguments or default arguments. (We know exactly what type of parameters we pass in at which point)

fun reformat(str: String,
             normalizeCase: Boolean = true,
             upperCaseFirstLetter: Boolean = true,
             divideByCamelHumps: Boolean = false,
             wordSeparator: Char = ' '){}// The default call mode
reformat(str)

// When using a non-default function call
reformat(str, true.true.false.'_')

// Use named arguments to make the code more readable
reformat(str,
         normalizeCase = true,
         upperCaseFirstLetter = true,
         divideByCamelHumps = false,
         wordSeparator = '_'
        )
// If there are some values that we don't need to change and there are default values
reformat(str, wordSeparator = '_'Reformat (STR, wordSeparator ='_'Reformat (STR, divideByCamelHumps =false ,  '_') cannot be called in this way and all parameters following the named arguments must be written as named arguments. reformat(str, divideByCamelHumps =false , wordSeparator = '_') the rightCopy the code

Vararg can be passed in as a named parameter by using the asterisk operator

Fun foo(vararg strings: String) {... } foo(strings = *arrayOf("a", "b", "c"))Copy the code

Function of ###1.2 Unit

If a function does not return any useful values, its return type is Unit. Unit is a type that has only one value, Unit. This value does not need to be explicitly returned:

fun printHello(name: String?).: Unit {
    if(name ! =null)
    println("Hello ${name}")
    else
    println("Hi there!")
    // 'return Unit' or 'return' is optional
}

// If there is no return value, you can omit it
fun printHello(name: String?). { …… }
Copy the code

1.3 Single-expression functions

When a function returns a single expression, you can omit the curly braces and specify the body of the code after the = symbol. We went from the traditional method to the concise method step by step

fun double(x: Int):Int{
	return x * 2
} 

// If a single expression is returned, the braces can be omitted.
fun double(x: Int): Int = x * 2

// The editor can also intelligently analyze our return value, omitting int
fun double(x: Int) = x * 2

Copy the code

1.4 Variable number of parameters (Varargs)

A function’s argument (usually the last one) can be marked with the vararg modifier, allowing a variable number of arguments to be passed to the function

fun <T> asList(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts) // ts is an Array
        result.add(t)
    return result
}

val list = asList(1.2.3)
Copy the code

Only one parameter can be labeled vararg. If the vararg argument is not the last argument in the list, you can pass the value of the argument that follows using named parameter syntax, or, if the argument has a function type, by passing a lambda outside the parentheses.

When we call vararg-, we can pass the arguments one by one, such as asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (precede the array with an *) :

val a = arrayOf(1.2.3)
val list = asList(-1.0, *a, 4)
Copy the code

1.5 Infix syntax

Functions marked with the infix keyword can also be called using infix notation (ignoring the call’s points and parentheses). The infix function must meet the following requirements:

  1. They must be member functions or extension functions;
  2. They must have only one parameter;
  3. Its arguments must not accept a variable number of arguments and must not have default values.
infix fun Int.shl(x: Int): Int { …… }

// Call the function with infix notation
1 shl 2

// Is equivalent to this
1.shl(2)
Copy the code

Infix function calls take precedence over arithmetic operators, type conversions, and the rangeTo operator. The following expression is equivalent:

  1. 1 SHL 2 + 3 and 1 SHL (2 + 3)
  2. 0 until n * 2 and 0 until (n * 2)
  3. xs union ys as Set<> 与 xs union (ys as Set<>)

Infix function calls, on the other hand, the priority is higher than the Boolean operators && and | |, is – with the in – check > and other operators. These expressions are also equivalent:

  1. A && B xor C and a && (b xor C)
  2. A xor b in C and (a xor b) in C

Note that infix functions always require the receiver and parameters to be specified. When using infix notation to call a method on the current receiver, you need to explicitly use this; It cannot be omitted like a regular method call. This is necessary to ensure non-fuzzy parsing

class MyStringCollection {
    infix fun add(s: String) { …… }

    fun build(a) {
        this add "abc"   / / right
        add("abc")       / / right
        add "abc"        // Error: recipient must be specified}}Copy the code

Kotlin’s Study Notes (9)