Lazy initialization and sealed classes

lazy initialization

background

Kotlin provides non-nullable variables to suppress null pointer problems.

While this feature ensures program security, it also brings us some coding problems.

Case: Imagine that there is a global variable a in your program, and the variable a is not initialized at the beginning of creation, so you make it equal to null.

Assuming that the type of a is String, because it is necessary to ensure that a is not empty, its type is declared as String?

private var a: String? = null

Next, every time the method in a needs to be called, it must be judged as empty (even if it has already been initialized), otherwise it cannot be compiled!

This problem becomes more pronounced when there are more and more instances of global variables in the code.

lazy initialization

To solve this problem, Kotlin uses the lateinit keyword to initialize variables.

private lateinit var a: String

The lateinit keyword tells the Kotlin compiler that I will initialize the variable later so that the variable does not need to be assigned a value of null.

In this way, when calling the method in the global variable a, there is no need to perform null judgment.

When using this object, you need to ensure that it has been initialized, otherwise a runtime error will occur!

Avoid repeated initialization

To avoid repeated initialization of variables, the following code can be used

if (!::a.isInitialized) {
    
     // 判断 a 是否初始化,如果未初始化执行代码块
            a = "ming ming" // 对 a 进行初始化操作
        }

::object.isInitialized is a fixed way of judging initialization.

Sealed

background

Create a new Result.kt file and write the following code in the file:

interface Result
class Success(val message:String):Result
class Failure(val error: Exception):Result

A Result interface is defined in the code, which is used to represent the execution result of an operation.

Define two classes to implement the Result interface, the Success class is used to represent the result of success, and the Failure class is used to represent the result of failure.

Then define a getResultMessage() to execute the information of the final execution result, the code is as follows

fun getResultMessage(result: Result) = when(result){
    
    
    is Success -> result.message
    is Failure -> result.error.message
    else -> throw IllegalArgumentException()
}

The getResultMessage() method receives a Result parameter.

We use the when statement to judge the type of Result, if it is Success, print a success message, and if it is Failure, return an error message.

To be fair, the code should end at this point. Because the execution result of the code either succeeds or fails, and there is no other situation.

But in order to satisfy Kotlin's syntax check , an else is written at the end to throw an exception ( in fact, this else can never be reached ).

In addition, if we add another class inheriting the Result interface and forget to add the corresponding execution code in getResultMessage(),

When the code is executed, the exception in else will be thrown directly.

Sealed

Sealed classes can easily solve the above problems. To declare a sealed class, you only need to add the keyword sealed before the class.

Transform the Result interface into a sealed class

sealed class Result 
class Success(val message:String):Result()
class Failure(val error: Exception):Result()

Next, pass in the sealed class as the condition in when, Kotlin will check which subclasses the sealed class has, and force you to deal with the conditions corresponding to each subclass, so that you can ensure that even if you do not write the else condition, no There will be situations where branches are missed.

fun getResultMessage(result: Result) = when(result){
    is Success -> result.message
    is Failure -> result.error.message
}

When we create a new Others class that inherits the Result sealed class, getResultMessage() will report an error.

We can add the processing of conditions corresponding to all subclasses through Add remaining branches.

Guess you like

Origin blog.csdn.net/jiaweilovemingming/article/details/125063960