The function is defined as follows.
//A function that increments and returns an Int type argument
fun increment(i: Int): Int {
return i + 1
}
fun function name
(argument list
): return type
This is the basic form.
Which value corresponds to which argument in a function call with many arguments It may be difficult to understand.
Kotlin has the ability to solve this problem.
/*
*I will order takoyaki
*
* @param isKarashiMayo Whether to select mustard mayonnaise
* @param isPutAonori Whether or not to put green laver
*
* @return An instance of takoyaki is returned
*/
fun oderTakoyaki(isKarashiMayo: Boolean, isPutAonori: Boolean): Takoyaki {
// ...
}
val takoyaki = oderTakoyaki(true, false)
//Which flag is green laver?
val takoyaki = oderTakoyaki(isKarashiMayo = true, isPutAonori = false)
//You can give a formal argument name to the caller
//Easy to read code intent
val takoyaki = oderTakoyaki(isPutAonori = false, isKarashiMayo = true)
//If you give it a name, it doesn't have to be in the order defined in the function.
I think there are many classes that have many overloads with different numbers of arguments. For example ...
By using default arguments in Kotlin, you can avoid such a situation where variations increase.
/*
*I will order takoyaki
*
* @param isKarashiMayo Whether to select mustard mayonnaise
* @param isPutAonori Whether or not to put green laver
*
* @return An instance of takoyaki is returned
*/
fun oderTakoyaki(isKarashiMayo: Boolean = false, isPutAonori: Boolean = true): Takoyaki {
// ...
}
//Arguments can be omitted at the time of calling. If omitted, the default value is used.
val takoyaki = oderTakoyaki()
You can add functions to existing classes later. Let's add a function to the String type that parses in our own date format.
fun String.toDate(): Date {
val format = SimpleDateFormat("yyyy year MM month dd day")
return format.parse(this)
}
val str = "March 09, 2019"
val date = str.toDate()
fun extended type
.function name
(argument list
): return value
Define it as ↑.
By the way, the usual function is ...
fun function name
(argument list
): return type
↑ It was like this.
Preceding the function name
with the extension target type
makes it an extension function.
By the way, this extension target object is called ** receiver object ** in Kotlin.
If the function consists of one expression, the {}
can be omitted.
Single-expression functions can also omit the return type if the return type is inferrable.
//Normal function
fun double(x: Int): Int {
return x * 2
}
//Described as a single expression function
fun double(x: Int): Int = x * 2
//Infer the return type with a single expression function
fun double(x: Int) = x * 2
Lambda expressions are written as ↓.
val sum = { x: Int, y: Int ->
x + y
}
{argument list
-> body
}
Or if there are no arguments
{Main body
}
It will be.
The implicit variable ʻit` can be used if the lambda expression has one parameter.
val double: (Int)->Int = {
it * 2
}
The functional type is described as follows.
(argument type
)-> return type
Lambda expressions are a costly mechanism. Kotlin's lambda expression is implemented as an anonymous class. Each time a lambda expression that captures a variable is executed, an instance of the anonymous class is created.
So, the inline function. The inline function is compiled by replacing the function body where it is called.
inline fun edit(context: DataBaseContext, block: (DataBaseContext.Transaction)->Unit) {
val transaction = context.beginTransaction() // 1.Transaction start
block(transaction) // 2.Argument lambda execution
transaction.commit() // 3.End of transaction
}
The inline function is effective A function that takes a lambda expression as an argument and executes it internally. The inline function also expands the argument lambda expression to the caller.
This is a sample that calls the Ueno inline function ʻedit`.
val dataBaseContext = DataBaseContext()
edit(dataBaseContext) { transaction ->
val newObject = Any()
transaction.add(newObject)
}
The ʻedit` function is expanded at compile time and looks like the following code (image)
val dataBaseContext = DataBaseContext()
//The edit function expands from here
val transaction = dataBaseContext.beginTransaction() // 1.Transaction start
val newObject = Any() // 2.Argument lambda expansion
transaction.add(newObject) // 2.Argument lambda expansion
transaction.commit() // 3.End of transaction
//The edit function expands so far
Kotlin generics lose type information at run time.
For example, the following function will result in a compilation error.
fun <T> mapFilter(list: List<Any>): List<T> {
return list.filter { it is T }
.map { it as T }
}
This is because the type parameter T
of the mapFilter
function is lost at run time.
Therefore, add the reified
modifier to the inline function.
//↓ Here!
inline fun <reified T> mapFilter(list: List<Any>): List<T> {
return list.filter { it is T }
.map { it as T }
}
By doing this, it will be expanded while retaining the type information at runtime.
The mapFilter
function can now be compiled.
Recommended Posts