Previous article – Kotlin collection sequences use, operator summary
This blog is about the problems I have encountered in learning Kotlin, if there is something wrong, I hope you can help me out, thank you.
A brief introduction to higher-order functions
In a word, higher-order functions: In Kotlin, higher-order functions are those that use functions as arguments or return values of a function.
The arguments are higher-order functions
Let’s take a look at the extension function in the String.kt file
/** * Returns the sum of all values produced by [selector] function applied to each character in the char sequence. */
// Inline functions are used inline with lambdas.
// CharSequence. Is an extension function
public inline fun CharSequence.sumByDouble(selector: (Char) - >Double): Double {
// The selector argument is also a fun, passing in a char and putting in a Double
var sum: Double = 0.0
for (element in this) {
sum += selector(element)
}
return sum
}
Copy the code
This function converts the passed string iterator to a Double, increments, and returns the sum of Double types.
Returns a higher-order function
Here is an example from the official website
// Argument one takes the Lock type and a function that takes no arguments and returns type T
fun <T> lock(lock: Lock, body:()->T):T{
lock.lock()
try {
// The function returns a value
return body()
}
finally {
lock.unlock()
}
}
Copy the code
Let’s look at it a little bit more directly with a pseudocode
fun toBeSynchronized(a) = sharedResource.operation()
val result = lock(lock, ::toBeSynchronized)
/ / short
val result = lock(lock, {sharedResource.operation()} )
Copy the code
Higher-order functions are commonly used
All concentrated in standard.kt
TODO
Source:
/**
* Always throws [NotImplementedError] stating that operation is not implemented.
*
* @param reason a string explaining why the implementation is missing.
*/
@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")
// Inline is added to reduce the elapsed time by eliminating the need to jump to the inline function
Copy the code
The run function
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
// Run also with apply also
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
Copy the code
This contract representation tells the compiler that the effect of calling the run function is to specify that the block lamba expression argument is called at the appropriate place. The appropriate place is that block lambda expressions can only be called during a call to the apply function. When run is called, block expressions cannot be executed. Invocationkind.exactly_once specifies that a block lambda expression can only be called once, and that the outer function must be an inline function. (Contracts are more like telling the compiler its own context.) This function is used when we need to execute a code block, and the code block is independent. That is, I can write some code in the run() function that is independent of the project, because it will not affect the normal operation of the project.
For example:
private fun printString(index: Int) {
val str = "kotlin"
var l = kotlin.run {
when (index) {
1- > {"java"
}
2- > {"php"
}
else- > {"lua"
}
}
}.length
print(str + l)
}
Copy the code
As in the above code, when print executes, it waits for the result of the run method block to return.
T.run()
T.run() and run() may not seem very different to the eye, but there will be quite a difference when used
Source:
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T. () - >R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
Copy the code
Let’s use a code to simulate the usage environment
private var str = "java"
fun printStr(a){
str.run {
print("${this.length}")
print("${this.last()}")
print("${first()}")}}Copy the code
This keyword can be used in the t. run method block in the above code to replace itself, or can be omitted, more suitable for multiple lines of code using the same object, if viewed through the source code, you can find that block() is a T type extension function.
For more higher-order functions like also with apply, check out Kotlin’s library functions: run, with, let, also, and apply
Next – Kotlin study Notes (14) Shallow reading coroutines