Kotlin introduced the concept of higher-order functions to improve coding efficiency in some scenarios
What are higher-order functions
Colloquially speaking, it is similar to the concept of higher-order functions in mathematics, that is, the parameters of functions can be functions. Of course, the return value can also be a function.
2. Analysis of kotlin high-order functions
1. View onClickListener (kotlin
tV.setOnClickListener {
//doSomeThing
}
Copy the code
The lamba expression inside is a function
Not very graphic? Now look at filter and map in the set
listOf(1, 2, 3)
.filter { it > 2 }
.map { it + 5 }
/**
* Returns a list containing only elements matching the given [predicate].
*/
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
Copy the code
The argument to filter and map is a lambda function
2. What is the use of higher-order functions
In the case of the filter function, for example, to implement a filter logic, it’s ok to say that if classA and classB both need to call this function, then the function needs to be compatible with both cases
fun filter(): Boolean {
if (classA) {
return true
} else if (classB) {
return false
}
return false
}
Copy the code
If else is fine, but if classC classD… We have to think about it. It clearly violates the open close principle. It is natural to be abstract rather than concrete, of course, abstract classes or interfaces.
If you implemented it the Java way, it would look like this
interface IJudge {
fun canFilter(): Boolean
}
class ClassA : IJudge {
override fun canFilter(): Boolean {
return true
}
}
class ClassB : IJudge {
override fun canFilter(): Boolean {
return false}} Fun filter(a:Int,b:Int,jugde: IJudge): Boolean {// add some logicreturn jugde.canFilter()
}
Copy the code
This is a tough one, so you have to add this interface for abstraction, and then write more code.
If you use higher order functions
Fun filter(a: Int,b:Int, canFilter: (a:Int,b:Int) -> Boolean): Boolean {// Add some logicreturnCanFilter (a,b)} // call 1 filter(1, 2) {a: Int, b: Int -> a * b > 10} Int -> a + b < 5 }Copy the code
This saves an interface, which is actually generated by the compiler
Third, the implementation of Kotlin higher-order functions
Let’s see how the Kotlin compiler works by decomcompiling that kotlin code into Java, okay
Kt: fun filter(a: Int,b:Int, canFilter: (a:Int,b:Int) -> Boolean): Boolean {// Add some logicreturn canFilter(a,b)
}
java:
public final boolean filter(int a, int b, @NotNull Function2 canFilter) {
Intrinsics.checkParameterIsNotNull(canFilter, "canFilter");
canFilter.invoke(a, b);
return (Boolean)canFilter.invoke(a, b);
}
Copy the code
Actually Functions built into KT. Kt
So from here we can get the above conclusion:
A) function can omit an interface that has only one method
Canfilter.invoke (a,b); canfilter.invoke (a,b); This is useful when a function needs to be nulled. For example, replacing interface callbacks with only one method can be callback? .invoke(a,b,c), because callbck? (a,b,c) will not compile.
C. Although the functions.kt file has a finite number of methods, it feels like lambda parameters are finite, up to 22 parameters, beyond which compilation will fail. But when it does, another functionn.kt is called
operator fun invoke(vararg args: Any?) : RCopy the code
But if who writes the function, directly pass more than 20 parameters are not sealed into an object or builder, even the legs have to be interrupted…….
Fourth, the discussion about higher-order function replacement interface
As discussed above, when an interface has only one method, you can indeed omit an interface by using higher-order functions instead.
But when an interface has more than one method, you obviously can’t replace it directly. It’s possible to wrap several functions together, but it still feels redundant.
In parallel development, one person writes the UI and one handles the business logic using the UI. First set the interface, interface method documentation is written, at a glance. In this respect, interfaces are much better, and higher-order functions are more convenient when there is only one simple method.