Understanding and applying generics in Kotlin

Preface

Generics is a concept used in programming to increase the flexibility and reusability of code. It allows us to write generic code that works on multiple types without having to write different code for each type.

Generic application

In Kotlin, generics can be applied to classes, functions, interfaces, etc. Below are some understandings and examples of generics in Kotlin.

1. Generic class

A generic class is a class that can use one or more type parameters in the class. These type parameters can be used in methods and properties in the class. For example, we can create a generic list class that allows different types of elements to be stored:

class MyList<T> {
    private val elements: MutableList<T> = mutableListOf()
    
    fun add(element: T) {
        elements.add(element)
    }
    
    fun get(index: Int): T {
        return elements[index]
    }
}

In the above example, T it is a type parameter that we can use in the class method to manipulate the elements in the list. By specifying different type parameters, we can create list instances that store elements of different types:

val stringList = MyList<String>()
stringList.add("Hello")
val firstString = stringList.get(0)

val intList = MyList<Int>()
intList.add(42)
val firstInt = intList.get(0)

2. Generic functions

Generic functions allow us to use type parameters in functions. This allows functions to perform the same operation on arguments of different types. For example, we can write a generic function to print elements of any type:

fun <T> printElement(element: T) {
    println(element)
}

In the above example, T is a type parameter that we can use in the function to print the elements passed to the function. We can call this function and pass different types of parameters:

printElement("Hello")  // 打印字符串
printElement(42)       // 打印整数

3. Generic interface

Generic interfaces allow us to use type parameters in the interface. This allows classes that implement the interface to specify type parameters according to their own needs. For example, we can define a generic container interface to store elements of different types:

interface Container<T> {
    fun add(element: T)
    fun get(index: Int): T
}

In the above example, T it is a type parameter that we can use in the methods of the interface to manipulate elements. Classes that implement this interface can specify type parameters according to their own needs:

class MyContainer<T> : Container<T> {
    private val elements: MutableList<T> = mutableListOf()
    
    override fun add(element: T) {
        elements.add(element)
    }
    
    override fun get(index: Int): T {
        return elements[index]
    }
}

In the above example, MyContainer the class implements  Container the interface and specifies type parameters  T. This means we can  MyContainer store and retrieve different types of elements in the class.

4. Type constraints

Sometimes we need to limit the type range of generic parameters. We can use colon (:) to specify type constraints. For example, we can require a generic parameter to implement an interface or inherit a class:

fun <T : Number> convertToString(value: T): String {
    // ...
}

fun <T> doSomething(item: T) where T : Comparable<T>, T : Serializable {
    // ...
}

5. Wildcard type

Sometimes we may not care about the specific type parameters and only need to specify a wildcard to represent any type. In Kotlin, use asterisk (*) as wildcard character. For example:

fun printList(list: List<*>) {
    // ...
}

Summarize

These are some basic uses of generics in Kotlin. By using generics, we can write more general, flexible, and reusable code. Hope these examples are helpful!

Guess you like

Origin blog.csdn.net/qq_39312146/article/details/133468330