¿Qué es Kotlin?
Kotlin
Es un lenguaje que se ejecuta encima JVM
de .
Fue Jetbrains
creado por , la empresa detrás de Jetbrains
muchas herramientas poderosas como la conocida . es un lenguaje muy simple, uno de sus principales objetivos es proporcionar un lenguaje potente manteniendo una sintaxis simple y optimizada.Java IDE IntelliJ IDEA
Kotlin
características de kotlin
Sus principales características son las siguientes:
- Ligero: Esto es
Android
muy importante para. Las bibliotecas requeridas por el proyecto deben ser lo más pequeñas posible.Android
Existe un límite estricto en la cantidad de métodos yKotlin
solo se han agregado alrededor de 6000 métodos adicionales. - Interoperabilidad: se comunica perfectamente
Kotlin
conJava
idiomas. Esto significa que podemosKotlin
usar cualquierJava
biblioteca existente en nuestro código, por lo tanto, aunque el lenguaje aún es joven, ya hay cientos de bibliotecas disponibles. Además de esto,Kotlin
el código se puedeJava
usar por código, lo que significa que podemos usar ambos lenguajes para crear software. Puede usarloKotlin
para desarrollar nuevas funciones mientras implementaJava
otras partes del código base. - Escritura fuerte: rara vez necesitamos especificar tipos en nuestro código porque el compilador puede inferir el tipo de una variable o el valor de retorno de una función en la mayoría de los casos. De esta forma obtienes dos beneficios: simplicidad y seguridad. Al
var
declarar un argumento variado,val
declarar un argumento inmutablevar
:var
es una variable mutable, que es una variable que se puede cambiar a otro valor mediante reasignación. Esta forma de declarar variablesJava
es la misma que declarar variables en .val
:val
es una variable de solo lectura. Esta forma de declarar una variable es equivalente a la variablejava
enfinal
. Unoval
debe inicializarse cuando se crea porque no se puede cambiar más adelante. El código anterior: var nombre = "ztz" println(nombre) nombre = "yif" println(nombre) val finalValue = "i v"; println(finalValue); El resultado es el siguiente: ztz yif iv - Seguridad aérea:
Java
el mayor problema esnull
. Si no senull
juzgan las variables o parámetros, es posible que se incluyan una gran cantidad de ellos en el programaNullPointerException
, pero son difíciles de detectar durante la codificación.Kotlin
Se utiliza explícitonull
, lo que nos obliga a comprobarlo si es necesarionull
. - Azúcar sintáctica
- Simplificación de clases, getter() implícito, setter()
- La implementación predeterminada de la interfaz.
- lambdas y funciones de orden superior
- Seguridad de puntero nulo, comprobación de puntero nulo en tiempo de compilación
- Mapa de operaciones de recopilación de streaming (), forEach ()
- nuevas características
- Expansión de funciones, expansión de atributos.
- proxy de atributo
Desarrollo ligero de Kotlin
Nulo seguro
Kotlin
es null
seguro. Si un tipo puede ser null
, entonces debemos agregar uno después del tipo ?
. De esta forma, debemos comprobar cada vez que se utiliza una variable de este tipo null
. Por ejemplo, el siguiente código no se compilará:
var artist: Artist? = null?
artist.print()
La línea 2 mostrará un error porque la variable no está null
marcada. Podemos hacer esto:
if (artist != null) {
? artist.print()?
}
Esto demuestra Kotlin
otra gran característica: la conversión de tipos inteligente. Si se marca el tipo de variable, no es necesario incluirla en el alcance de verificación. Con esto, ahora podemos usar variables como tipos if
en . Esto también se aplica a otras inspecciones. Hay una forma más sencilla de comprobarlo , que es utilizarlo antes de llamar a la función del objeto . Incluso puedes proporcionar un enfoque alternativo a través de operadores :artist
Artist
null
?
Elvis
?
val name = artist?.name ?: ""
datos de clase de datos
En Java
, si queremos crear una clase de datos o POJO
una clase (una clase que simplemente guarda algún estado), necesitamos crear una clase con muchos campos getters
y setters
, y tal vez proporcionar métodos toString
y :equals
public class Artist {
private long id;
private String name;
private String url;
private String mbid;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMbid() {
return mbid;
}
public void setMbid(String mbid) {
this.mbid = mbid;
}
@Override public String toString() {
return "Artist{
" +
"id=" + id +
", name='" + name + '\'' +
", url='" + url + '\'' +
", mbid='" + mbid + '\'' +
'}';
}
}
En Kotlin
, el código anterior se puede escribir de la siguiente manera:
data class Artist (?
var id: Long,
var name: String,
var url: String,
var mbid: String)
Kotlin
Utilice propiedades en lugar de campos. Básicamente, una propiedad es un campo más su getter
AND setter
.
Interoperabilidad
Kotlin
Proporciona excelentes funciones de interoperabilidad, que son Android
muy útiles para el desarrollo. lambda
Uno de ellos es el mapeo entre una interfaz con un único método y una expresión. Por lo tanto, el siguiente oyente de clics:
view.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
toast("Click")?
}
?})
Se puede escribir así:
view.setOnClickListener {
toast("Click") }
Además, getters
y setters
se asignan automáticamente a propiedades. No hay ninguna penalización en el rendimiento porque el código de bytes en realidad simplemente llama al getters
AND original setters
. Como se muestra en el siguiente código:
supportActionBar.title = title
textView.text = title
contactsList.adapter = ContactsYifAdapter()
expresión lambda
Lambda
Las expresiones simplificarán el código en gran medida, pero lo importante es que con la ayuda de Lambda
expresiones podemos hacer cosas que antes eran imposibles o muy problemáticas de implementar. Las expresiones nos permiten Lambda
pensar en los problemas de una manera más funcional. Lambda
Una expresión es en realidad un tipo específico y el tipo define una función. Por ejemplo, podemos definir una variable como esta:
val listener: (View) -> Boolean
Esta variable puede declarar una función que toma view
y devuelve esta función. Necesitamos definir el comportamiento de la función mediante cierre:
val listener = {
view: View -> view is TextView }
La función anterior recibirá una instancia de View
y, si view
es así TextView
, la devolverá true
. Dado que el compilador puede inferir el tipo, no es necesario especificarlo. También puede ser más explícito:
val listener: (View) -> Boolean = {
view -> view is TextView }
Con la ayuda de Lambda
expresiones, podemos abandonar el uso de interfaces de devolución de llamada. Simplemente configura la función a la que quieres que te llamen más tarde:
fun asyncOperation(value: Int, callback: (Boolean) -> Unit) {
...
callback(true)?
}
asyncOperation(5) {
result -> println("result: $result") }
Hay una forma más concisa: si la función solo recibe un parámetro, puedes usar palabras reservadas it
:
asyncOperation(5) {
println("result: $it") }
función de orden superior
lambda`本身作为一等公民,它是有类型的。比如下面这个加法表达式sum的类型为`(Int, Int) -> Int。
val sum: (Int, Int) -> Int = { x, y -> x+y }
Es natural que una variable tenga un tipo. Dado que el valor de entrada y retorno de una función de orden superior es lambda
, es normal que su tipo sea un poco extraño.
fun main(args: Array<String>) {
// 自定义高阶函数, lambda 表达式 作为入参
listOf("1", "2", "3", "4").myForEach {
println(it) }
// 自定义高阶函数, lambda 表达式 作为返回值
// getLogger()("I'm a Closure")
var logger = getLogger()
logger("I'm a Closure")
}
/**
* 接受一个 lambda 表达式, 作为遍历任务
*/
fun <T> List<T>.myForEach(doTask: (T) -> Unit){
for(item in this)
doTask(item)
}
/**
* 返回一个 lambda 表达式(闭包), 如: 日志输出工具 logger
*/
fun getLogger(): (String) -> Unit{
// return { println(it) }
return fun (it: String){
println(it)
}
}
PD: Al ver getLogger()
este uso, probablemente te des cuenta de que puedes js
escribir cierres como ese.
La implementación predeterminada de la interfaz.
Como sugiere el nombre, significa que la interfaz puede tener una implementación predeterminada del cuerpo del método como una clase abstracta. Lo atribuyo al azúcar sintáctico, porque java8
ya existe exactamente lo mismo en China, y la palabra clave correspondiente se llama default
.
interface A {
fun foo() {
println("A") } // 默认实现, 打印"A"
fun bar()
}
interface B {
fun foo() {
println("B") }
fun bar() {
println("bar") }
}
// 多继承时,显式指定 super<A>.foo() 以去冲突
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
override fun bar() {
super.bar()
}
}
Mapa de operaciones de recopilación de streaming (), forEach ()
Los operadores de conjuntos de transmisión son muy comunes y se pueden encontrar en cualquier idioma, sin embargo, si no admiten expresiones funcionales, será complicado escribirlos. En el siguiente ejemplo, la conexión de algunos operadores deja muy clara la lógica de operación: si la demanda cambia más tarde, como cambiar el orden descendente a ascendente, solo es necesario sortedDescending()
cambiar una línea, lo cual es muy flexible.
fun main(args: Array<String>){
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
list.filter {
it%2==0 } // 取偶数
.map{
it*it } // 平方
.sortedDescending() // 降序排序
.take(3) // 取前 3 个
.forEach {
println(it) } // 遍历, 打印
}
// 输出:
100
64
36
expandir
La expansión de esto parece hacerse en el modo decorador. Su efecto es agregar funciones sin cambiar el código fuente. Por ejemplo, si queremos Activity
agregar uno toast()
, no necesitamos desinstalar la clase base en absoluto. Esto simplifica mucho el trabajo, especialmente para algunas jar
clases empaquetadas.
fun Activity.toast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}
/**
* @author yif
*
* 函数拓展, 属性拓展
*/
fun main(args: Array<String>) {
val list = listOf("1", "2", "3", "4")
// 函数拓展
list.myForEach {
println(it) }
// 属性拓展
println("last: ${
list.lastItem}")
}
/**
* 拓展 List 类, 加一个自定义的遍历方法
*/
fun <T> List<T>.myForEach(doTask: (T) -> Unit){
for(item in this)
doTask(item)
}
/**
* 拓展 List 类, 加一个自定义的长度属性
*/
val <T> List<T>.lastItem: T
get() = get(size - 1)
// 输出:
1
2
3
4
last: 4
proxy de atributo
Delega las propiedades de get()
la set()
propiedad a una clase para que pueda realizar algunas operaciones adicionales durante get()
y . set()
como:
- Carga lenta
- Observador (notifica automáticamente cuando cambian las propiedades)
- Tomando la carga diferida como ejemplo para el juicio de atributos no vacíos,
lazySum
puede requerir operaciones complejas, por lo que la delegamos alazy
. Como puede ver, solo se calcula la primera carga y los valores posteriores se toman directamente, lo que mejora la eficiencia. val lazySum: Int by lazy { println("comenzar a calcular lazySum ...") var sum = 0 for (i in 0…100) sum += i println("lazySum calculada!n") sum // Devuelve el resultado del cálculo } fun main (args: Array<String>) { println(lazySum) println(lazySum) } // Salida: comienza a calcular lazySum... ¡lazySum calculada! 5050 5050 Anko esAnko
unaKotlin
biblioteca desarrollada por el equipo para simplificarAndroid
el desarrollo. Su objetivo principal es proporcionar una vistaDSL
que se pueda declarar usandoKotlin
código: verticalLayout { val nombre = editText() botón("Di Hola") { onClick { brindis("Hola, ${name.text}!") } } } También proporciona algunas otras funciones útiles. Por ejemplo, navegue a otrosActivity
Y pase valores a otras interfaces: startActivity("id" a res.id, "name" a res.name) startActivity<ContentActivity>( Pair(Constants.CONTENT_TITLE_KEY, useWebsiteBean.name), Pair(Constants.CONTENT_URL_KEY, useWebsiteBean .link ), Pair(Constants.CONTENT_ID_KEY, useWebsiteBean.id) ) Resumen Kotlin realmente simplifica el trabajo de desarrollo de Android en muchos aspectos. Aumentará tu productividad y solucionará algunos problemas habituales de una forma muy diferente y sencilla. Utilicemos Kotlin para un desarrollo rápido y ágil .