Function argument confusion

When a function has multiple arguments, and there are multiple arguments of the same type right next to each other, it is often not clear whether the arguments are passed in the correct position, and the readability of the function is severely affected. The caller is required to jump to the corresponding place of the function and match the parameters to the parameter list in the function definition. This can cause a lot of trouble and confusion for the function caller.

fun <T> joinToString(collection: Collection<T>,
                     separator:String,
                     prefix:String,
                     postfix:String):String{
    val result = StringBuilder(prefix)
    for ((index,element) in collection.withIndex()){
        if (index > 0)
            result.append(separator)
        result.append(element)
    }
    result.append(postfix)
    return result.toString()
}
Copy the code

In this case, you might be able to rely on the IDE for optimization. For example, Idea has been optimized for this. When filling in parameters of the function, the parameter name corresponding to the parameter will be prompted.

Named parameters

Kotlin optimizes this situation at the syntactic level by displaying names that indicate parameters when a Kotlin defined function is called. Such arguments are called named arguments.

When specifying the name of one parameter, avoid confusion; all other parameters must be named. (Since the names are explicitly specified, there is no need to pass the arguments in the order they were originally defined.)

joinToString(array,prefix = "(",separator = ",", postfix = "]")
Copy the code

Note:

  • Since the parameter name is displayed, it means that when the parameter name or method name is changed, the parameter name or method name that is explicitly indicated also needs to be changed. In this case, Rename can be modified using Idea. (Select method name or parameter name -> Refactor -> Rename)
  • You cannot use named parameters when calling java-defined functions because before Java8 you could not store parameter names in class files. Kotlin needs to be Java6 compatible. Therefore, the compiler does not recognize the names of function arguments.

Function overload

In Java, function overloading is supported. This results in multiple functions with the same name and only slightly different parameters. When you call a function that omits some arguments, it may not be clear which function is being called. (For example, the Thread class has eight constructors)

The default parameters

Kotlin can avoid creating multiple overloaded functions by simply specifying the default values of the parameters. Such function arguments with default values are called default arguments. When used with named parameters, it is very convenient to assign values to specified parameters, so as to realize overloading.

fun <T> joinToString(collection: Collection<T>,
                          separator:String = ",",
                          prefix:String = "",
                          postfix:String = ""):String
Copy the code

All you need to do is pass in the concrete collection object, and the function will evaluate it using the default values of the default arguments.

Of course, there is no problem passing in the corresponding parameters in the order they are defined.

Val String = joinToString(array) // There is no problem passing prefixes, separators and suffixes as before."(".",")
val string = joinToString(array,"(".","."]"Separator = joinToString(array,separator =) // Separator = joinToString(array,separator =";")
Copy the code

JvmOverloads improve Kotlin’s interactivity with Java

There is no concept of default parameters in Java, and when Kotlin’s function is called from Java, all parameter values must be explicitly passed. To enable Java callers to call overloaded functions of this method, annotate it with @jvmoverloads. At compile time, the compiler omits the last argument one by one, generating Java overloaded functions.

Local function

Programmers tend to believe that smaller methods are better, and that it is best to break them up into single, small local methods that are eventually organized and called, rather than vertically lengthy code fragments. Many times, however, there is no clear relationship between the decomposed small methods and you end up with a class containing many small methods.

Local functions are supported in Kotlin. Local functions declare methods in methods, and internal methods can get the parameters and local variables of external functions. Each small method can be defined as a local method, providing the desired compact structure without additional syntax overhead.

data class Person(val age:String? ,val name:String?) fun daqi(person: Person){if (person.age == null){
        throw IllegalArgumentException()
    }
    if(person.name == null){throw IllegalArgumentException()}Copy the code

Convert to local functions:

Fun daqi(person: person){// It needs to be defined at the top level, otherwise fun personFileIsEmpty(value:String? ,fileName:String){if (value == null){
            throw IllegalArgumentException("$fileName is null")
        }
    }
    
    personFileIsEmpty(person.age,"age")
    personFileIsEmpty(person.name,"name"}}Copy the code

The disadvantage of local functions is that local functions cannot be declared inline, nor can functions that have local functions be declared inline. There is currently no way to avoid the cost of calling such functions.

References:

  • Kotlin in Action
  • Kotlin website

Android Kotlin series:

Kotlin’s Knowledge generalization (I) — Basic Grammar

Kotlin knowledge generalization (2) – make functions easier to call

Kotlin’s knowledge generalization (iii) — Top-level members and extensions

Kotlin knowledge generalization (4) – interfaces and classes

Kotlin’s knowledge induction (v) — Lambda

Kotlin’s knowledge generalization (vi) — Type system

Kotlin’s knowledge induction (7) — set

Kotlin’s knowledge induction (viii) — sequence

Kotlin knowledge induction (ix) — Convention

Kotlin’s knowledge induction (10) — Delegation

Kotlin’s knowledge generalization (xi) — Higher order functions

Kotlin’s generalization of knowledge (xii) – generics

Kotlin’s Generalization of Knowledge (XIII) — Notes

Kotlin’s Knowledge induction (xiv) — Reflection