Kotlin actual combat [III] representation and selection

preface

In this chapter, we will learn how to implement representation and selection through enumeration and when in Kotlin.

1, Enumeration representing and selecting

1.1 definition of enumeration

Let's take a look at the usage in java:

public enum Color
{
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

Usage in kotlin:

enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

You will find that using enum in kotlin also uses class, which is different from that in java. Think about why?

Knowledge points

In Kotlin, enum is the so-called soft keyword: it has a unique meaning only when it is placed before the class keyword. But you can use it as a regular name elsewhere.
class is still a keyword. Continue to declare variables with things like clazzName.
Like java, attributes and methods can be declared in enumerations

1.2 enumeration class with attributes

First look at the code in java:

public enum Color
{
    RED(255, 0, 0), //When each variable is created, the attribute value is specified
    ORANGE(255, 165, 0), //A comma is required
    YELLOW(255, 255, 0),
    GREEN(0, 255, 0),
    BLUE(0, 0, 255),
    INDIGO(75, 0, 130),
    VIOLET(238, 130, 238);

    private int r;
    private int g;
    private int b;

    Color(int r, int g, int b)
    {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    public int getRGB(){
        return (r * 256 + g * 256 + b*256);
    }

    public int getR()
    {
        return r;
    }

    public int getG()
    {
        return g;
    }

    public int getB()
    {
        return b;
    }
}

Is it super much? Let's take a look at kotlin. Is it much less and refreshing in an instant

enum class Color(
        val r: Int, val g: Int, val b: Int //Declare properties of enumeration constants
) {
    RED(255, 0, 0), //When each variable is created, the attribute value is specified
    ORANGE(255, 165, 0), //A comma is required
    YELLOW(255, 255, 0),
    GREEN(0, 255, 0),
    BLUE(0, 0, 255),
    INDIGO(75, 0, 130),
    VIOLET(238, 130, 238);
    fun rgb() = (r * 256 + g * 256 + b*256)//Defines the method of enumeration
}

As can be seen from the two examples, when you define an enumeration constant, you need to provide attribute values for it.

This example shows the only thing Kotlin syntax needs a semicolon: if you define any method in an enumeration class, the semicolon distinguishes between an enumeration constant list and a method declaration.

Next, let's look at the processing of enumeration:

2, Indicates When to select

2.1 use "when" to handle enumerations

Next, we use when to select enumeration. We enter a color and return a corresponding string

fun getMnemonic(color: Color) =   //Directly return an expression of "when"
    when (color) {                //Returns the string of the response if the color is equal to the enumeration constant
        Color.RED -> "Richard"
        Color.ORANGE -> "Of"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        Color.INDIGO -> "In"
        Color.VIOLET -> "Vain"
    }

println(getMnemonic(Color.BLUE)) // Battle

As we can see from the above code, you don't need to write break statements for each branch (omitting break in java usually leads to bug s).

You can merge multiple values into the same branch, just separated by commas.

As follows:

fun getWarmth(color: Color) = when(color) {
    Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
    Color.GREEN -> "neutral"
    Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
}
 println(getWarmth(Color.ORANGE)) //warm

The above example uses the enumeration constant with the full name to specify the name of the Color enumeration class. You can simplify your code by importing constants:

import ch02.colors.Color //Import the Color class declared in another package
import ch02.colors.Color.*//Display imported enumeration constants by name

fun getWarmth(color: Color) = when(color) {
    RED, ORANGE, YELLOW -> "warm" //Import constants by name
    GREEN -> "neutral"
    BLUE, INDIGO, VIOLET -> "cold"
}

2.2 use any object in the "when" structure

The when structure in kotlin is much more powerful than switch in java. Switch must require a constant (enumeration constant, string, or numeric literal) as a branch condition, and when can use any object.

Let's write a function to mix the two colors:

fun mix(c1: Color, c2: Color) =
    when (setOf(c1, c2)) {//The parameter of the when expression can be any instance, which is used to be checked by the branch condition
        setOf(RED, YELLOW) -> ORANGE//Enumerates color pairs that can be mixed
        setOf(YELLOW, BLUE) -> GREEN
        setOf(BLUE, VIOLET) -> INDIGO
        else -> throw Exception("Dirty color")//Execute this if no branch can match
    }
println(mix(BLUE, YELLOW))//GREEN

The Kotlin standard library contains a setOf function to create a set, including instances specified by parameters; A set is a set, and the order of its items is not important. Therefore, if setOf(c1, c2) and setOf(RED, YELLOW) are equal, it means that otherwise c1 is RED and c2 is YELLOW, or vice versa.

2.3 use when without parameters

The above example is a little inefficient, because every time you call this function, it will create several Set instances, just to check whether two colors match the other two colors. Normally, it's not a problem. However, if this function is called frequently, it is worth rewriting the code in another way to avoid GC. You can do this with a when expression without parameters. Although the code is less readable, it is the price paid for better performance.

fun mixOptimized(c1: Color, c2: Color) =
    //No arguments passed to when
    when {
        (c1 == RED && c2 == YELLOW) || (c1 == YELLOW && c2 == RED) -> ORANGE
        (c1 == YELLOW && c2 == BLUE) || (c1 == BLUE && c2 == YELLOW) -> GREEN
        (c1 == BLUE && c2 == VIOLET) || (c1 == VIOLET && c2 == BLUE) -> INDIGO
        else -> throw Exception("Dirty color")
    }
println(mixOptimized(BLUE, YELLOW)) //GREEN

2.4 code blocks as branches of "if" and "when"

Both if and when can use code blocks as branches.

In this example, the last expression in the code block is the result. If you want to add a log to the example function, you can do it in the code block and return it with the last value.

fun evalWithLogging(e: Expr): Int =
    when (e) {
        is Num -> {
            println("num: ${e.value}")
            e.value //If e is of type Num, this is the last expression in the code block and is returned
        }
        is Sum -> {
            val left = evalWithLogging(e.left)
            val right = evalWithLogging(e.right)
            println("sum: $left + $right")
            left + right//If the expression is returned when e is of type Sum
        }
        else -> throw IllegalArgumentException("Unknown expression")
    }
    println(evalWithLogging(Sum(Sum(Num(1), Num(2)), Num(4))))
    //num: 1
    //num: 2
    //sum: 1 + 2
    //num: 4
    //sum: 3 + 4
    //7

Rule: "the last expression in the code block is the return value", which holds true in all places where the code block is used and a result is expected.

Now that we have learned how to choose from many options correctly, let's look at how to iterate things in the next chapter.

Article transferred from https://cloud.tencent.com/developer/article/1385735 If there is infringement, please contact to delete.

Relevant video recommendations:

Android performance optimization learning [2]: APP startup speed optimization_ Beep beep beep_ bilibili
[Android advanced system learning]: time-consuming record of automation method realized by bytecode stake insertion technology_ Beep beep beep_ bilibili
Android performance optimization learning [2]: APP startup speed optimization_ Beep beep beep_ bilibili
[Android interview topic]: the interview was asked about interprocess communication, but you don't even know what Binder is_ Beep beep beep_ bilibili
BAT interview skills - what do you know about network programming for Android interview_ Beep beep beep_ bilibili

Posted by sigmadog on Thu, 04 Nov 2021 04:59:42 -0700