¡Acostúmbrate a escribir juntos! Este es el tercer día de mi participación en el "Nuggets Daily New Plan · April Update Challenge", haz clic para ver los detalles del evento .
1. Tres formas de implementación singleton
object
Mira el código primero:
object Pro {
}
复制代码
Es tan simple realizar el singleton de Pro. Podemos descompilarlo en código Java para ver el principio de implementación específico:
public final class Pro {
@NotNull
public static final Pro INSTANCE;
private Pro() {
}
static {
Pro var0 = new Pro();
INSTANCE = var0;
}
}
复制代码
En primer lugar Pro
, el constructor de la clase se declara como private
, en segundo lugar, puede ver que se trata de un singleton implementado por un bloque de código estático.Usando la característica de que el bloque de código estático de la clase solo se ejecutará una vez, pertenece 线程安全且饿汉式
a ;
En java Pro.INSTANCE
se obtiene este singleton, mientras que kotlin Pro
obtiene directamente el singleton
lazy
Código primero:
class Pro private constructor() {
companion object {
val INSTANCE by lazy {
Pro()
}
}
}
复制代码
Utiliza principalmente las propiedades declaradas por el objeto complementario como variables estáticas, y el modo de implementación predeterminado de lazy es lock thread-safe. Esta es una 线程安全且懒汉式
implementación singleton. Para lazy
obtener más información, consulte una de las prácticas de desarrollo de Kotlin.
- bloqueo de doble verificación
Código anterior:
@Volatile
var singleton: Pro? = null
fun getInstance(): Pro {
if (singleton == null) {
synchronized(Pro::class.java) {
if (singleton == null) {
singleton = Pro()
}
}
}
return singleton!!
}
复制代码
Lo anterior es la implementación de kotlin del bloqueo de verificación doble de Java, donde:
@Volatile
Garantizar el orden de las instrucciones del código.getInstance
Las capas interna y externa del método estánsingleton
vacías para garantizarsingleton
que la inicialización se haya completado y que los subprocesos no necesiten competir por los bloqueos.getInstance
La capa interna del método estásingleton
vacía para garantizar que si el subproceso anterior se ha inicializadosingleton
, los subprocesos posteriores no deben inicializarse nuevamente.
Como puede ver, este es un 线程安全且懒汉式
singleton implementado de una manera
2. typealias
Toma un alias para un tipo complejo
Esta typealias
palabra clave se utiliza principalmente para dar un alias al tipo. A continuación se describen los dos escenarios de uso siguientes:
- alias de tipo de función
En el desarrollo diario, los tipos de función deben usarse comúnmente, como
//拼接Int和String类型并返回String类型
val block: ((Int, String) -> String)? = null
复制代码
Este tipo de función (Int, String) -> String)
es engorroso de escribir y poco legible, y ahora es typealias
el momento de cargar:
typealias Concat = (Int, String) -> String
val block: Concat? = null
复制代码
No solo (Int, String) -> String)
es Concat
conveniente de usar, sino que también es fácil ver el escenario de uso de este tipo de función: empalme
- Pase genérico simplificado
Cuando usamos ViewModel
, a menudo podemos encapsular el retorno de la interfaz de la siguiente manera:
class MainViewModel: ViewModel() {
val data: MutableLiveData<Response<String>> = MutableLiveData()
fun test() {
data.value = Response("haha")
}
data class Response<T>(val data: T? = null)
}
复制代码
Utilizado Response
para encapsular la devolución del servidor, el tipo genérico T
representa la clase de entidad en la que se pueden deserializar los datos de respuesta.
Como puede ver arriba, cada definición MutableLiveData
debe declararse en su tipo genérico Response<T>
, porque la nuestra Response
es una encapsulación unificada de todas las respuestas de la interfaz, y es un tipo definido, y el tipo que contiene Response<T>
es el tipo que debe especificarse dinámicamente T
cada momento en que se crea .MutableLiveData
¿Puedes omitirlo? Ahora es el momento de Response<T>
subir :Response
typealias
typealias ExternalLiveData<T> = MutableLiveData<MainViewModel.Response<T>>
复制代码
Entonces, cada vez que lo cree MutableLiveData
, puede escribirlo así:
val data1: ExternalLiveData<String> = MutableLiveData()
复制代码