"Tutorial minimalista de Kotin" Capítulo 15 Operaciones de E / S de archivos Kotlin, expresiones regulares y subprocesos múltiples

Capítulo 15 Operación de E / S de archivos Kotlin y subprocesos múltiples

Cuando usamos la operación de E / S de archivos de Groovy, se siente muy conveniente. El mismo Kotlin también tiene una API de operación de IO de archivos útil. De manera similar, se han realizado algunas extensiones prácticas a la función de expresión regular de Java en Kotlin. Y el multihilo en Kotlin encapsula principalmente la API de multihilo de Java. Debido a que estos Java ya tienen muchas API básicas, Kotlin no repite la implementación por sí mismo, sino que amplía las funciones prácticas sobre la base de Java.

En este capítulo, presentaremos las operaciones de E / S de archivos Kotlin, las expresiones regulares y el contenido relacionado con subprocesos múltiples.

15.1 Introducción a Kotlin IO

Las operaciones de E / S de Kotlin están todas bajo el paquete kotlin.io. El principio de Kotlin es que Java ya lo tiene. Si es fácil de usar, úselo directamente. Si no lo es o no es fácil de usar, encapsúlelo y extiéndalo basándose en la clase original. Por ejemplo, Kotlin escribe una función de extensión para la clase File. Esta es la misma idea que la API extendida de Groovy.

15.2 Terminal IO

¡La muy larga declaración de salida de Java System.out.println () ha continuado hasta el presente! El mismo trabajo se puede hacer en C ++ con un simple cout <<. Por supuesto, si es necesario, podemos encapsular directamente System.out.println () como un método de impresión simple en el proyecto.

Es muy simple en Kotlin, simplemente use las dos funciones globales println o print. Ya no necesitamos un prefijo largo. Por supuesto, si somos nostálgicos y solo queremos usar System.out.println (), Kotlin aún admite el uso directo (interoperabilidad perfecta con Java).

>>> System.out.println("K")
K
>>> println("K")
K

La función println aquí en Kotlin se implementa de la siguiente manera

@kotlin.internal.InlineOnly
public inline fun println(message: Any?) {
    System.out.println(message)
}

Por supuesto, Kotlin solo está encapsulado sobre la base de System.out.println ().

Leer datos desde la terminal también es muy simple.El método más básico es la función global readLine, que lee una línea directamente desde la terminal como una cadena. Si necesita más procesamiento, puede utilizar varias funciones de procesamiento de cadenas proporcionadas por Kotlin para procesar y convertir cadenas.

La clase de Kotlin para encapsular la E / S de terminal está en el archivo fuente stdlib / src / kotlin / io / Console.kt.

15.3 Operación de E / S de archivo

Kotlin proporciona muchas funciones de extensión útiles para java.io.File, estas funciones de extensión se encuentran principalmente en los siguientes tres archivos fuente:

kotlin / io / files / FileTreeWalk.kt
kotlin / io / files / Utils.kt
kotlin / io / FileReadWrite.kt

Al mismo tiempo, Kotlin también hizo extensiones simples para InputStream, OutputStream y Reader. Se encuentran principalmente en los dos archivos fuente siguientes:

kotlin / io / IOStreams.kt
kotlin / io / ReadWrite.kt

La serialización de Koltin usa directamente el alias de tipo de la clase de serialización de Java:

internal typealias Serializable = java.io.Serializable

Presentemos brevemente las operaciones de lectura y escritura de archivos Kotlin.

15.3.1 Leer archivo

Leer todo el contenido del archivo

Si simplemente leemos un archivo, podemos usar el método readText (), que devuelve directamente todo el contenido del archivo. El ejemplo de código es el siguiente

    /**
     * 获取文件全部内容字符串
     * @param filename
     */
    fun getFileContent(filename: String): String {
        val f = File(filename)
        return f.readText(Charset.forName("UTF-8"))
    }

Usamos directamente el objeto File para llamar a la función readText para obtener el contenido completo del archivo, que devuelve una cadena. Si especifica la codificación de caracteres, puede especificarla pasando el parámetro Charset, y el valor predeterminado es la codificación UTF-8.

Si queremos obtener el contenido de cada línea del archivo, simplemente podemos split("\n")obtener una matriz del contenido de cada línea.

Obtenga el contenido de cada línea del archivo

También podemos llamar directamente a la función readLines encapsulada por Kotlin para obtener el contenido de cada línea del archivo. La función readLines devuelve una lista que contiene el contenido de cada línea.

    /**
     * 获取文件每一行内容,存入一个 List 中
     * @param filename
     */
    fun getFileLines(filename: String): List<String> {
        return File(filename).readLines(Charset.forName("UTF-8"))
    }

Manipulación directa de matrices de bytes

Si queremos manipular directamente la matriz de bytes del archivo, podemos usar readBytes (). Si desea utilizar el método tradicional de Java, también puede utilizarlo tan libremente como Groovy en Kotlin.

    //读取为bytes数组
    val bytes: ByteArray = f.readBytes()
    println(bytes.joinToString(separator = " "))

    //直接像 Java 中的那样处理Reader或InputStream
    val reader: Reader = f.reader()
    val inputStream: InputStream = f.inputStream()
    val bufferedReader: BufferedReader = f.bufferedReader()
}

15.3.2 Escribir archivo

Similar a leer archivos, escribir archivos también es muy simple. Podemos escribir cadenas o flujos de bytes. También puede utilizar directamente Java Writer o OutputStream.

Archivo de sobrescritura

    fun writeFile(text: String, destFile: String) {
        val f = File(destFile)
        if (!f.exists()) {
            f.createNewFile()
        }
        f.writeText(text, Charset.defaultCharset())
    }

Escribir archivo al final

    fun appendFile(text: String, destFile: String) {
        val f = File(destFile)
        if (!f.exists()) {
            f.createNewFile()
        }
        f.appendText(text, Charset.defaultCharset())
    }

15.4 Recorrer el árbol de archivos

Al igual que Groovy, Kotlin también proporciona funciones convenientes para recorrer el árbol de archivos. Para recorrer el árbol de archivos, debe llamar al método de extensión walk (). Devolverá un objeto FileTreeWalk, que tiene algunos métodos para configurar la dirección transversal y la profundidad. Para obtener más detalles, consulte la documentación de la API FileTreeWalk.

Consejo: enlace del documento de API FileTreeWalk https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/-file-tree-walk/

El siguiente ejemplo recorre todos los archivos de la carpeta especificada.

    fun traverseFileTree(filename: String) {
        val f = File(filename)
        val fileTreeWalk = f.walk()
        fileTreeWalk.iterator().forEach { println(it.absolutePath) }
    }

Código de prueba:

    @Test fun testTraverseFileTree() {
        KFileUtil.traverseFileTree(".")
    }

Ejecute el código de prueba anterior, generará todos los subdirectorios y sus archivos en el directorio actual.

También podemos recorrer todos los archivos del subdirectorio del archivo actual y almacenarlos en un iterador

    fun getFileIterator(filename: String): Iterator<File> {
        val f = File(filename)
        val fileTreeWalk = f.walk()
        return fileTreeWalk.iterator()
    }

Atravesamos todos los archivos del subdirectorio en el archivo actual, también podemos filtrar según las condiciones y almacenar los resultados en una secuencia

    fun getFileSequenceBy(filename: String, p: (File) -> Boolean): Sequence<File> {
        val f = File(filename)
        return f.walk().filter(p)
    }

Código de prueba:

    @Test fun testGetFileSequenceBy() {
        val fileSequence1 = KFileUtil.getFileSequenceBy(".", {
            it.isDirectory
        })
        fileSequence1.forEach { println("fileSequence1: ${it.absoluteFile} ") }

        val fileSequence2 = KFileUtil.getFileSequenceBy(".", {
            it.isFile
        })
        fileSequence2.forEach { println("fileSequence2: ${it.absoluteFile} ") }

        val fileSequence3 = KFileUtil.getFileSequenceBy(".", {
            it.extension == "kt"
        })
        fileSequence3.forEach { println("fileSequence3: ${it.absoluteFile} ") }
    }

Ejecute el código de prueba anterior en el proyecto, tendrá un resultado similar al siguiente:

...
...

fileSequence3: /Users/jack/kotlin/chapter15_file_io/./src/main/kotlin/com/easy/kotlin/fileio/KFileUtil.kt 
fileSequence3: /Users/jack/kotlin/chapter15_file_io/./src/main/kotlin/com/easy/kotlin/fileio/KNetUtil.kt 
fileSequence3: /Users/jack/kotlin/chapter15_file_io/./src/main/kotlin/com/easy/kotlin/fileio/KShellUtil.kt 
fileSequence3: /Users/jack/kotlin/chapter15_file_io/./src/test/kotlin/com/easy/kotlin/fileio/KFileUtilTest.kt 


15.5 Funcionamiento de E / S de red

Kotlin agrega dos métodos de extensión a java.net.URL, readBytes y readText. Podemos utilizar fácilmente estos dos métodos con expresiones regulares para realizar la función de los rastreadores web.

A continuación, simplemente escribimos algunos ejemplos de funciones.

Obtenga la función HTML de respuesta de la URL de acuerdo con la URL


fun getUrlContent(url: String): String {
    return URL(url).readText(Charset.defaultCharset())
}

Obtenga la función de matriz de bits de respuesta de URL de acuerdo con la URL

fun getUrlBytes(url: String): ByteArray {
    return URL(url).readBytes()
}

Escribir matriz de bytes de respuesta de URL en el archivo

fun writeUrlBytesTo(filename: String, url: String) {
    val bytes = URL(url).readBytes()
    File(filename).writeBytes(bytes)
}

El siguiente ejemplo simplemente obtiene el código fuente de la página de inicio de Baidu.

getUrlContent("https://www.baidu.com")

El siguiente ejemplo obtiene el flujo de bits de una imagen de acuerdo con la URL y luego llama al método readBytes () para leer el flujo de bytes y escribirlo en el archivo.

writeUrlBytesTo("图片.jpg", "http://n.sinaimg.cn/default/4_img/uplaod/3933d981/20170622/2fIE-fyhfxph6601959.jpg")

Podemos ver el "picture.jpg" descargado en la carpeta correspondiente del proyecto.

15.6 biblioteca estándar de kotlin.io

La biblioteca io de Kotlin es principalmente una biblioteca io que amplía Java. A continuación ofrecemos brevemente algunos ejemplos.

appendBytes

Agregar matriz de bytes al archivo

Firma del método:

fun File.appendBytes(array: ByteArray)

appendText

Agregar texto al archivo

Firma del método:


fun File.appendText(
    text: String, 
    charset: Charset = Charsets.UTF_8)

bufferedReader

Obtener el BufferedReader del archivo

Firma del método:

fun File.bufferedReader(
    charset: Charset = Charsets.UTF_8, 
    bufferSize: Int = DEFAULT_BUFFER_SIZE
): BufferedReader

bufferedWriter

Obtener el BufferedWriter del archivo

Firma del método:

fun File.bufferedWriter(
    charset: Charset = Charsets.UTF_8, 
    bufferSize: Int = DEFAULT_BUFFER_SIZE
): BufferedWriter

copyRecursively

Copie el archivo o copie recursivamente el directorio y todos sus subarchivos en la ruta especificada. Si el archivo en la ruta especificada no existe, se creará automáticamente.

Firma del método:

fun File.copyRecursively(
    target: File, 
    overwrite: Boolean = false, // 是否覆盖。true:覆盖之前先删除原来的文件
    onError: (File, IOException) -> OnErrorAction = { _, exception -> throw exception }
): Boolean
Consejo: documentación de la API de Kotlin para las funciones de extensión de archivo https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/index.html
Acerca de kotlin.io, la siguiente documentación de API está aquí https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/index.html

15.7 Ejecutar la línea de comandos de Shell

Usamos la operación de E / S de archivos de Groovy que se siente muy fácil de usar, por ejemplo

package com.easy.kotlin

import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4)
class ShellExecuteDemoTest {
    @Test
    def void testShellExecute() {
        def p = "ls -R".execute()
        def output = p.inputStream.text
        println(output)
        def fname = "我图.url"
        def f = new File(fname)
        def lines = f.readLines()
        lines.forEach({
            println(it)
        })
        println(f.text)
    }
}

Las operaciones de E / S de archivos y E / S de red en Kotlin son tan simples como Groovy.

Además, del código anterior, podemos ver que es muy sencillo ejecutar comandos de terminal con Groovy:

def p = "ls -R".execute()
def output = p.inputStream.text

En Kotlin, actualmente no existe tal función para extender la clase String y Process. De hecho, es muy sencillo ampliar dicha función. Podemos expandirnos completamente por nosotros mismos.

Primero, extendamos la función execute () de String.

fun String.execute(): Process {
    val runtime = Runtime.getRuntime()
    return runtime.exec(this)
}

Luego, extendamos una función de texto a la clase Process.

fun Process.text(): String {
    var output = ""
    //	输出 Shell 执行的结果
    val inputStream = this.inputStream
    val isr = InputStreamReader(inputStream)
    val reader = BufferedReader(isr)
    var line: String? = ""
    while (line != null) {
        line = reader.readLine()
        output += line + "\n"
    }
    return output
}

Después de completar las dos funciones de extensión simples anteriores, podemos ejecutar comandos de terminal como Groovy en el siguiente código de prueba:

val p = "ls -al".execute()

val exitCode = p.waitFor()
val text = p.text()

println(exitCode)
println(text)

De hecho, a través del estudio de muchos ejemplos anteriores, podemos ver que las funciones de extensión de Kotlin son bastante prácticas. La API de lenguaje Kotlin también hace un uso extensivo de funciones extendidas.

15.8 Expresiones regulares

Además de Pattern, Matcher y otras clases en Java que todavía podemos usar en Kotlin, Kotlin también proporciona una clase de expresión regular kotlin / text / regex / Regex.kt, creamos una expresión regular a través del constructor Regex .

15.8.1 Construcción de expresiones Regex

Utilice el constructor Regex

>>> val r1 = Regex("[a-z]+")
>>> val r2 = Regex("[a-z]+", RegexOption.IGNORE_CASE)

La opción de concordancia RegexOption es una opción de concordancia regular en la clase de Java Pattern que se usa directamente.

Utilice la función de extensión toRegex de String

>>> val r3 = "[A-Z]+".toRegex()

15.8.2 Función Regex

Regex proporciona una gran cantidad de funciones simples y prácticas, como se muestra en la siguiente tabla

Nombre de la función Función descriptiva
coincidencias (entrada: CharSequence): Boolean Todas las cadenas de entrada coinciden
containsMatchIn (entrada: CharSequence): Booleano Al menos una coincidencia de la cadena de entrada
matchEntire (entrada: CharSequence): MatchResult? Todas las cadenas de entrada coinciden y se devuelve un objeto de resultado coincidente
reemplazar (entrada: CharSequence, reemplazo: Cadena): Cadena Reemplace la parte coincidente de la cadena de entrada con el contenido del reemplazo
reemplazar (entrada: CharSequence, transform: (MatchResult) -> CharSequence): String Reemplace el valor coincidente en la cadena de entrada con el nuevo valor después de la función de transformación
encontrar (entrada: CharSequence, startIndex: Int = 0): MatchResult? Devuelve el primer valor coincidente en la cadena de entrada.
findAll (input: CharSequence, startIndex: Int = 0): Sequence Devuelve una secuencia de MatchResult de todos los valores coincidentes en la cadena de entrada

A continuación damos ejemplos sencillos de las funciones anteriores.

matches

Si la cadena de entrada coincide con la expresión regular, devuelve verdadero; de lo contrario, devuelve falso.

>>> val r1 = Regex("[a-z]+")
>>> r1.matches("ABCzxc")
false
>>> 

>>> val r2 = Regex("[a-z]+", RegexOption.IGNORE_CASE)
>>> r2.matches("ABCzxc")
true

>>> val r3 = "[A-Z]+".toRegex()
>>> r3.matches("GGMM")
true

containsMatchIn

Devuelve verdadero si hay al menos una coincidencia en la cadena de entrada y falso si no hay ninguna coincidencia.

>>> val re = Regex("[0-9]+")
>>> re.containsMatchIn("012Abc")
true
>>> re.containsMatchIn("Abc")
false

matchEntire

La cadena de entrada coincide con la expresión regular y devuelve un objeto MatcherMatchResult; de lo contrario, devuelve nulo.

>>> val re = Regex("[0-9]+")
>>> re.matchEntire("1234567890")
kotlin.text.MatcherMatchResult@34d713a2
>>> re.matchEntire("1234567890!")
null

Podemos acceder al valor de MatcherMatchResult para obtener el valor coincidente.

>>> re.matchEntire("1234567890")?.value
1234567890

Dado que el retorno de la función matchEntire es un objeto que acepta valores NULL MatchResult, aquí usamos el símbolo de llamada segura ?..

replace(input: CharSequence, replacement: String): String

Reemplace la parte coincidente de la cadena de entrada con el contenido de reemplazo.

>>> val re = Regex("[0-9]+")
>>> re.replace("12345XYZ","abcd")
abcdXYZ

Podemos ver que "12345XYZ" en 12345una coincidencia con el [0-9]+contenido de la expresión regular , se reemplaza abcd.

replace(input: CharSequence, transform: (MatchResult) -> CharSequence): String

Reemplace el valor coincidente en la cadena de entrada con el nuevo valor después de la función de transformación.

>>> val re = Regex("[0-9]+")
>>> re.replace("9XYZ8", { (it.value.toInt() * it.value.toInt()).toString() })
81XYZ64

Podemos ver que 9XYZ8el número 8 y 9 son [0-9]+contenidos coincidentes de expresiones regulares , que son mapas de función de transformación respectivamente (it.value.toInt() * it.value.toInt()).toString()reemplazados por los nuevos valores de 81 y 64.

find

Devuelve el primer objeto MatcherMatchResult coincidente en la cadena de entrada.

>>> val re = Regex("[0-9]+")
>>> re.find("123XYZ987abcd7777")
kotlin.text.MatcherMatchResult@4d4436d0
>>> re.find("123XYZ987abcd7777")?.value
123

findAll

Devuelve una secuencia de MatchResult de todos los valores coincidentes en la cadena de entrada.

>>> val re = Regex("[0-9]+")
>>> re.findAll("123XYZ987abcd7777")
kotlin.sequences.GeneratorSequence@f245bdd

Podemos recorrer todos los valores coincidentes para cada uno

>>> re.findAll("123XYZ987abcd7777").forEach{println(it.value)}
123
987
7777

15.8.3 Uso de clases de expresión regular de Java

Además de las funciones proporcionadas por Kotlin anteriormente, todavía podemos usar la API de expresión regular de Java en Kotlin.

val re = Regex("[0-9]+")
val p = re.toPattern()
val m = p.matcher("888ABC999")
while (m.find()) {
    val d = m.group()
    println(d)
}

La salida del código anterior:

888
999

15.9 multiproceso de Kotlin

No hay una palabra clave sincronizada en Kotlin.
No hay una palabra clave volátil en Kotlin.
Any de Kotlin es similar al Object de Java, pero no hay métodos wait (), notificar () y notificar a todos ().

Entonces, ¿cómo funciona la concurrencia en Kotlin? No se preocupe, dado que Kotlin se apoya sobre los hombros de Java, por supuesto, el soporte para la programación de múltiples subprocesos es indispensable: Kotlin simplifica nuestra codificación encapsulando clases de subprocesos en Java. Al mismo tiempo, también podemos usar algunas anotaciones específicas, usar directamente las palabras clave de sincronización en Java, etc. A continuación, presentamos brevemente el contenido relacionado de la programación de subprocesos múltiples utilizando Kotlin.

15.9.1 Crear hilo

Normalmente tenemos dos formas de crear hilos en Java:

  • Ampliar la clase Thread
  • O instanciarlo y pasar un Runnable a través del constructor

Debido a que podemos usar fácilmente clases de Java en Kotlin, se pueden usar ambos métodos.

Crear usando expresiones de objeto

    object : Thread() {
        override fun run() {
            Thread.sleep(3000)
            println("A 使用 Thread 对象表达式: ${Thread.currentThread()}")
        }
    }.start()

Este código usa las expresiones de objeto de Kotlin para crear una clase anónima y anular el método run ().

Usar expresiones Lambda

Aquí se explica cómo pasar un Runnable a una instancia de Thread recién creada:

    Thread({
        Thread.sleep(2000)
        println("B 使用 Lambda 表达式: ${Thread.currentThread()}")
    }).start()

No vemos Runnable aquí, es muy conveniente usar directamente la expresión Lambda anterior para expresar en Kotlin.

hay una manera mas facil? Mira la explicación a continuación.

Utilice la función de hilo encapsulado de Kotlin

Por ejemplo, escribimos el siguiente código de hilo

    val t = Thread({
        Thread.sleep(2000)
        println("C 使用 Lambda 表达式:${Thread.currentThread()}")
    })
    t.isDaemon = false
    t.name = "CThread"
    t.priority = 3
    t.start()

Se puede decir que las siguientes cuatro líneas son código estándar. En Kotlin, este paquete de operaciones está simplificado.

    thread(start = true, isDaemon = false, name = "DThread", priority = 3) {
        Thread.sleep(1000)
        println("D 使用 Kotlin 封装的函数 thread(): ${Thread.currentThread()}")
    }

Este código es más sencillo y más limpio. De hecho, la función thread () abstrae y encapsula el código repetitivo que se usa a menudo en nuestra práctica de programación. Su implementación es la siguiente:

public fun thread(start: Boolean = true, isDaemon: Boolean = false, contextClassLoader: ClassLoader? = null, name: String? = null, priority: Int = -1, block: () -> Unit): Thread {
    val thread = object : Thread() {
        public override fun run() {
            block()
        }
    }
    if (isDaemon)
        thread.isDaemon = true
    if (priority > 0)
        thread.priority = priority
    if (name != null)
        thread.name = name
    if (contextClassLoader != null)
        thread.contextClassLoader = contextClassLoader
    if (start)
        thread.start()
    return thread
}

Esta es solo una función de envoltura muy conveniente, simple y práctica. En el ejemplo anterior, podemos ver que Kotlin simplifica el código repetitivo al extender la API de subprocesos de Java.

15.9.2 Bloques y métodos de sincronización

sincronizado no es una palabra clave en Kotlin, se reemplaza por la anotación @Synchronized. La declaración del método de sincronización en Kotlin se verá así:

    @Synchronized fun appendFile(text: String, destFile: String) {
        val f = File(destFile)
        if (!f.exists()) {
            f.createNewFile()
        }
        f.appendText(text, Charset.defaultCharset())
    }

La anotación @Synchronized tiene el mismo efecto que sincronizada en Java: marca el método JVM como sincronizado. Para el bloque sincronizado usamos la función synchronized (), que usa el bloqueo como parámetro:

    fun appendFileSync(text: String, destFile: String) {
        val f = File(destFile)
        if (!f.exists()) {
            f.createNewFile()
        }

        synchronized(this){
            f.appendText(text, Charset.defaultCharset())
        }
    }

Básicamente lo mismo que Java.

15.9.3 Campos variables

De manera similar, Kotlin no tiene la palabra clave volátil, pero tiene la anotación @Volatile.

@Volatile private var running = false
fun start() {
    running = true
    thread(start = true) {
        while (running) {
            println("Still running: ${Thread.currentThread()}")
        }
    }
}

fun stop() {
    running = false
    println("Stopped: ${Thread.currentThread()}")
}

@Volatile marcará el campo de respaldo de JVM como volátil.

Por supuesto, en Kotlin tenemos una biblioteca de concurrencia de corrutinas más útil. En la práctica de la ingeniería de código, podemos elegir libremente según la situación real.

Resumen del capítulo

Kotlin es un lenguaje con una sólida ingeniería y practicidad. A partir del archivo IO, las expresiones regulares y los subprocesos múltiples presentados en este capítulo, podemos comprender el principio básico de Kotlin: hacer un uso completo del ecosistema Java existente, basado en esto Una extensión más sencilla y práctica mejorará enormemente la productividad de los programadores. A partir de esto, también nos dimos cuenta del concepto minimalista en la programación de Kotlin: abstracción, encapsulación y expansión continuas para hacerlo más simple y práctico.

Código de muestra para este capítulo: https://github.com/EasyKotlin/chapter15_file_io

Además, el autor integró el contenido de este capítulo y escribió una aplicación web de rastreo de imágenes simple usando SpringBoot + Kotlin. Los lectores interesados ​​pueden consultar el código fuente: https://github.com/EasyKotlin/chatper15_net_io_img_crawler

En el próximo capítulo, y nuestro último capítulo, rompamos con la JVM y usemos directamente Kotlin Native para desarrollar una aplicación Kotlin que se compila directamente en código máquina y se ejecuta.


Comunidad de desarrolladores de Kotlin

Centrarse en compartir Java, Kotlin, Spring / Spring Boot, MySQL, redis, neo4j, NoSQL, Android, JavaScript, React, Node, programación funcional, ideas de programación, "alta disponibilidad, alto rendimiento, alto tiempo real" diseño de arquitectura de sistema distribuido a gran escala tema.

Diseño de arquitectura de sistema distribuido a gran escala de alta disponibilidad, alto rendimiento y tiempo real

Marco distribuido: Zookeeper, marco de middleware distribuido, etc.
Almacenamiento distribuido: GridFS, FastDFS, TFS, MemCache, redis, etc.
Base de datos distribuida: Cobar, tddl, Amoeba,
computación en la nube Mycat , big data,
virtualización de algoritmos de IA , nativos en la nube Tecnología
Marco informático distribuido: MapReduce, Hadoop, Storm, Flink, etc.
Mecanismo de comunicación distribuido: Dubbo, llamadas RPC, datos remotos compartidos, colas de mensajes, etc.
Cola de mensajes MQ: Kafka, MetaQ, RocketMQ
cómo construir un sistema de alta disponibilidad: basado en hardware, software Realización de algunas soluciones típicas como middleware y arquitectura de sistema: HAProxy, Corosync + Sistema de middleware de suite de clúster de alta disponibilidad basado en Pacemaker
Arquitectura Mycat evolución distribuida
Los problemas detrás de Big Data Join: contradicciones y reconciliación de datos, red, memoria y capacidades informáticas
Problemas de alto rendimiento en sistemas distribuidos Java: ¿AIO, NIO, Netty o frameworks de desarrollo propio?
Mecanismo de envío de eventos de alto rendimiento: modelo de grupo de subprocesos, modelo de disruptor, etc. . .

La madera que abraza nace al final del molino; la plataforma de nueve pisos comienza desde el sótano; el viaje de mil millas comienza con un solo paso. Si no acumula pasos, no puede llegar a mil millas; si no acumula pequeños arroyos, no puede convertirse en un río.

Introducción a Kotlin

Kotlin es un lenguaje que no es de investigación. Es un lenguaje de programación de grado industrial muy pragmático. Su misión es ayudar a los programadores a resolver problemas en la práctica real de la ingeniería. El uso de Kotlin mejora la vida de los programadores de Java. Los errores de puntero nulo en Java, el largo código repetitivo que desperdicia el tiempo, las restricciones de sintaxis detalladas, etc., desaparecen en Kotlin. Kotlin es simple y pragmático, con una sintaxis concisa y poderosa, segura y expresiva y extremadamente productiva.

Java nació en 1995 y tiene una historia de 23 años. La última versión actual es Java 9. En el proceso de desarrollo continuo y prosperidad del ecosistema JVM, también nacieron lenguajes hermanos como Scala, Groovy y Clojure.

Kotlin también es un excelente miembro de la familia JVM. Kotlin es un lenguaje moderno (la versión 1.0 se lanzó en febrero de 2016). Su propósito original es optimizar los defectos del lenguaje Java como Scala, proporcionar características de lenguaje de programación más simples y prácticas y resolver problemas de rendimiento, como el tiempo de compilación. JetBrains ha hecho un gran trabajo en estas áreas.

Características del lenguaje Kotlin

Después de desarrollar en Java durante muchos años, es genial poder probar algo nuevo. Si eres un desarrollador de Java, Kotlin será muy natural y fluido. Si es un desarrollador de Swift, se sentirá familiar, como Nullability. Las características del lenguaje Kotlin son:

1. Conciso

Reducir significativamente la cantidad de código repetitivo.

2. 100% de interoperabilidad con Java

Kotlin puede interactuar directamente con las clases de Java y viceversa. Esta característica nos permite reutilizar directamente nuestro código base y migrarlo a Kotlin. Porque la interoperabilidad de Java está en casi todas partes. Podemos acceder directamente a las API de la plataforma y las bases de código existentes, mientras disfrutamos y usamos todas las potentes funciones del lenguaje moderno de Kotlin.

3. Función de extensión

Kotlin es similar a C # y Gosu, brinda la capacidad de proporcionar nuevas extensiones funcionales para clases existentes sin tener que heredar de la clase o usar ningún tipo de patrones de diseño (como patrones decoradores).

4. Programación funcional

El lenguaje Kotlin primero admite programación funcional, al igual que Scala. Tiene características funcionales básicas como funciones de orden superior y expresiones lambda.

5. Parámetros predeterminados y con nombre

En Kotlin, puede establecer un valor predeterminado para los parámetros en una función y darle un nombre a cada parámetro. Esto ayuda a escribir código fácil de leer.

6. Soporte de herramientas de desarrollo de gran alcance

Y debido a que es producido por JetBrains, tenemos una excelente compatibilidad con IDE. Aunque la conversión automática de Java a Kotlin no es 100% correcta, de hecho es una muy buena herramienta. Cuando se utilizan las herramientas de IDEA para convertir código Java a código Kotlin, el 60% -70% del código resultante se puede reutilizar fácilmente y el costo de modificación es pequeño.

Además de sus características de sintaxis concisas y poderosas, Kotlin también tiene una API muy práctica y un ecosistema construido a su alrededor. Por ejemplo: API de colección, extensión IO, API de reflexión, etc. Al mismo tiempo, la comunidad de Kotlin también proporciona una gran cantidad de documentos y muchos materiales de aprendizaje, así como REPL en línea.

Un lenguaje de programación moderno que hace más felices a los desarrolladores. Código abierto para siempre

Imagen de "Kotlin desde la entrada al combate avanzado" (Chen Guangjian, Tsinghua University Press)

Imagen de "Kotlin desde la entrada al combate avanzado" (Chen Guangjian, Tsinghua University Press)

https://kotlinlang.org/

Supongo que te gusta

Origin blog.csdn.net/universsky2015/article/details/108669487
Recomendado
Clasificación