Directory:

• 1. Scope functions apply, Also and let, run

• 2. Delegate by keyword

• 3. Use when instead of switch and if + N else if

• 4. Inline, noinline, crossinline

• 5. Operator overloading and infix expressions

• 6. Extension functions, extension properties, anonymous extensions

1 Recommended usage scenarios of the scope functions apply, Also, let, and run

1.1 No need to return other types of objects Use apply, Also, usually used when an object is initialized

1.2 You need to return other types of objects using let, run, usually used for object references

2 Delegate by keyword

2.1 Common attribute delegate by lazy

Maintain a singleton member that is created on first access, a bit like lazy loading in Java

They use it three ways, and the effect is the same. Pessimistic lock will be used when creating, and the lock object is the current class of declared members, which will generate [lock] overhead. In the actual use process, two points need to be carefully considered, otherwise the gain is not worth the loss

  • 1 Determine whether lazy loading is required
  • 2 Determine whether to enable thread safety

2.2 Custom property delegate

Scenario analysis: Suppose the following two variables need to be operated directly on both set and get. Can this be avoided by writing the same boilerplate code twice? This is where the custom property delegate comes in

Create a delegate object that implements the get set method and initiates the logic for the supplementary properties operation

Called by the by keyword

It looks like magic, but it’s not dark magic, because the compiler automatically creates the relevant code logic, and you can see it by decompilating it, right

2.3 Do I have to do whatever I want? The official documents are also bad

So that seems like a nice thing to do, but type safety aside in this case, the point is that we’re using Kotlin to eliminate npes but the official documentation here shows you how to write an NPE using kotlin features without even knowing it, right

Can you avoid NPE by writing it normally? Of course you can. The compiler can help you avoid that

2.4 Static proxy implementation using delegate editing

3 use when instead of switch or even if + N else if

But when is also easy when out of the pit

Here is the first condition is BooleanCompanionObject actual compiled code. The INSTANCE that is the problem, this is very dangerous, maybe never expected Note: in front of the when condition without is is to determine the specific value

4 Inline, noinline, crossinline

4.1 Inline is used to save overhead on anonymous functions

  • Do not use the inline

  • Use the inline

  • Reduced the depth of the call stack

But it can also inflate the code (because it will copy all the calls), and as Google GDE says, reducing the call stack doesn’t improve performance much

The bottom line is to optimize performance by using the idea of compile-time constants, such as const for variables (static final in Java) and inline for functions

So if a function requires function arguments and the function is called frequently, consider using inline

4.2 noinline: disables inlining

In the inline scenario, using a function as an object is disallowed by default

Because of the inline optimization, the preAction object does not exist at all, so noinline is used

4.3 Crossinline: Inline reinforcement

In the following code, which function does return terminate?

Using the inline mechanism to simulate the compiled pseudocode, you can see that she ends up with the external main method

This is entirely logical and expected. A Lambda expression for the function argument to an inline function, allowing return

What if the function argument is wrapped up in another internal call?

This is where crossinline comes in

However, return is no longer available, thus avoiding the problem of whom retrun should exit.

Simple usage scenarios:

  • Inline needs to be considered only if a function type parameter is included in the function’s receive argument
  • Use noinline when function type arguments need to be used as objects
  • Function type arguments need to be called indirectly using Crossinline

Warning: Inline is used across Modules with the following problems

Declare a class in a Library, define a protecte inline function, and access a protecte member in an internal Lambda. Inherit the class in another App Module and access the inline function. Error: No access permission

This seems to be a kotlin bug, and at least the compiler should give an error

Operator overloading and infix expressions

fun main(a) {
    val point = Point(10.20)
    println("Unary minus sign${-point}")  Point(x=-10, y=-20)

    val p1 = Point(1.1)
    val p2 = Point(1.1)

    println("Binary +${p1 + p2}")
    println("Dual -${p1 - p2}")

    println("Infix greater than${p1 moreThan p2}")}Operator overloading: overrides the underlying operator function (calls the function as an operator symbol)
/// Infix expression: custom operator (not operator, only letter)

Public operator fun plus(other: Int) public operator fun plus(other: Int) public operator fun plus(other: Int) public operator fun plus(other: Int) Int operator overloading allows us to extend operators such as + - */ to any object

// Overloads the -------operator-----------------------
data class Point(val x: Int.val y: Int)

// One yuan [-] no. -obj
operator fun Point.unaryMinus(a) = Point(-x, -y)


// Binary [+] obj1 + obj2
operator fun Point.plus(p: Point): Point {
    return Point(x+p.x,y+p.y)
}
//二元 [-] 号  obj1 - obj2
operator fun Point.minus(p: Point): Point {
    return Point(x-p.x,y-p.y)
}

/* Kotlin allows you to declare a function as an infix using the infix keyword to simplify the expression on the call: a.morethan (b) -> a moreThan b */

// Infix expression ----------infix---------------------
infix fun Point.moreThan(p:Point):Boolean{
    return x*y > p.x * p.y
}
Copy the code

6. Extension properties, extension functions, anonymous extensions

Kotlin extensions have a wide range of application scenarios, so the expanded code is easy to expand, not easy to manage, prone to abuse, resulting in increased coupling, breaking the outer code boundary.

Permission priority suggestions:

  • Class private
  • File a private
  • Package private
  • Private module
  • The global general

6.1 Practical examples of expanded attributes

6.2 Extension Function

6.3 Anonymous Extension

Inline + anonymous extensions, such as let, apply, and other built-in extensions

Reference:

  • Kotlin official documentation
  • Throwing line Hencoder course