Making the address

Functions and Lambda expressions

  • Lambda expressions
  • Inline function

    Infix representation of a function

    Infix notation

  • First of all, its conditions of use:
    • They are member functions or extension functions
    • They only have one parameter
    • They use the infix keyword
  • Practical usage: Let’s take a look at some of Kotlin’s source code

 /** Shifts this value left by [bits]. */
    public infix fun shl(bitCount: Int): Int
    /** Shifts this value right by [bits], filling the leftmost bits with copies of the sign bit. */
    public infix fun shr(bitCount: Int): Int
    /** Shifts this value right by [bits], filling the leftmost bits with zeros. */
    public infix fun ushr(bitCount: Int): Int


/**
 * Creates a tuple of type [Pair] from this and [that].
 *
 * This can be useful for creating [Map] literals with less noise, for example:
 * @sample samples.collections.Maps.Instantiation.mapFromPairs
 */
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)


/**
 * Returns a set containing all elements that are contained by both this set and the specified collection.
 * 
 * The returned set preserves the element iteration order of the original collection.
 */
public infix fun <T> Iterable<T>.intersect(other: Iterable<T>): Set<T> {
    val set = this.toMutableSet()
    set.retainAll(other)
    return set
}


/**
 * Returns a progression from this value down to the specified [to] value with the step -1.
 * 
 * The [to] value has to be less than this value.
 */
public infix fun Short.downTo(to: Short): IntProgression {
    return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
}

`Copy the code

When we define a function or extension function of a class, we use infix notation if the function takes arguments of the same class and returns values

Higher-order functions and lambda expressions

Lambda expressions

  • This might be a little hard for some of you to learn, but it’s really easy to just switch gears and remember the following points. After reading, you can happily look at kotlin source code to learn.
  • A lambda expression or anonymous function is a “functional literal”, that is, an undeclared function, passed as an expression.
  • Function type :() -> T
  • Kotlin source code using a large number of lambda expressions, so that later in their own code, will also use a lot, this is also very simple, we remember this point: Functions that take functions as arguments or return values are higher-order functions. Kotlin generally takes arguments to higher-order functions in the form of functional literals (literal functions). A higher-order function takes another lambda expression as its last argument, and the lambda expression argument can be passed outside the parentheses argument list.
  • Kotlin’s lambda expressions and higher-order functions can save us a lot of Java interfaces. The OnClickListenter interface is omitted from the following interface
// Simply modify the viewsetOnClickListenter
class Main2Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        var view = View()
        view.setOnClickListenter { 
            it->it.toHome()
        }
    }
}
class View{
    fun toHome() {

    }
    fun setOnClickListenter(listerner: (v:View) -> Unit) { listerner(this); }}Copy the code
  • The receiver is the object that receives the function, that is, the object that calls the function
  • Function literal with receiver: Methods on the receiver object can be called without any additional qualifiers. This is similar to extension functions, which allow you to access members of the receiver object within the function body. When we write a higher-order function and find that we need to use the method inside the argument object in a lambda expression, we use the function literal with the receiver. There are many such functions in kotlin’s source code, as illustrated below:

  /**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
  @kotlin.internal.InlineOnly
  public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

/**
 * Calls the specified function[block] with `this` value as its receiver and returns `this` value. */ @kotlin.internal.InlineOnly public inline fun <T>  T.apply(block: T.() -> Unit): T { block();return this }

/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }Copy the code

However, there are several functions that are often used in our project, such as: now I have a book, I need to classify it by its current price, and then I need to get the name of the book


class Main2Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        var book = Book()
        var name = book.apply {
            var price = getPrice()
            if (price < 50) {
                Toast.makeText(this@Main2Activity,"Less than 50", toast.length_long).show()//this@Main2Activity is this expressiontype = "Cheap books"
            }else{
                Toast.makeText(this@Main2Activity,"More than 50", Toast.LENGTH_LONG).show()
                type = "Your book"
            }
        }.getName()
    }
}
class Book{
    var type:String? = null
    fun getName():String {
        return "youxin"
    }
    fun getPrice():Int {
        return100}}Copy the code
  • The receiver is the object that receives the function, that is, the object that calls the function
  • This expression