《Kotlin 程序设计》第四章 Kotlin 语法基础

第四章 Kotlin 语法基础

定义包

包的声明应处于源文件顶部:

package my.demo

import java.util.*

// ……

目录与包的结构无需匹配:源代码可以在文件系统的任意位置。

定义函数

完整的 Kotlin 方法定义语法为

[访问控制符] fun 方法名(参数列表) [:返回值类型] {}

Kotlin 可以省略变量定义的类型声明,但是在定义参数列表和定义返回值类型时则必须明确指定类型(这个类型推断Kotlin居然没做,这地方用起来比Scala,Groovy要繁琐点)。

例如,定义一个带有两个 Int 参数、返回 Int 的函数:


fun sum(a: Int, b: Int): Int { // kotlin中的返回值类型必须明确指定
    return a + b
}

fun main(args: Array<String>) {
    print("sum of 3 and 5 is ")
    println(sum(3, 5))
}

将表达式作为函数体、返回值类型自动推断的函数:

fun sum(a: Int, b: Int) = a + b
fun main(args: Array<String>) {
    println("sum of 19 and 23 is ${sum(19, 23)}")
}

函数返回无意义的值:

fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}
fun main(args: Array<String>) {
    printSum(-1, 8)
}

Unit 返回类型可以省略:

fun printSum(a: Int, b: Int) {
    println("sum of $a and $b is ${a + b}")
}
fun main(args: Array<String>) {
    printSum(-1, 8)
}

变长参数函数

同 Java 的变长参数一样,Kotlin 也支持变长参数

//在Java中,我们这么表示一个变长函数
public boolean hasEmpty(String... strArray){
    for (String str : strArray){
        if ("".equals(str) || str == null)
            return true;
    }
    return false;
}

//在Kotlin中,使用关键字vararg来表示

fun hasEmpty(vararg strArray: String?): Boolean{
    for (str in strArray){
        if ("".equals(str) || str == null)
            return true 
    }
    return false
}

定义局部变量

使用val 定义一次赋值(只读)的局部变量:

fun main(args: Array<String>) {
    val a: Int = 1  // 立即赋值
    val b = 2   // 自动推断出 `Int` 类型
    val c: Int  // 如果没有初始值类型不能省略
    c = 3       // 明确赋值
    println("a = $a, b = $b, c = $c")
}

使用var定义可变变量:

fun main(args: Array<String>) {

    var x = 5 // 自动推断出 `Int` 类型
    x += 1

    println("x = $x")
}

代码注释

正如 Java 和 JavaScript,Kotlin 支持行注释及块注释。

// 这是一个行注释

/* 这是一个多行的
   块注释。 */

与 Java 不同的是,Kotlin 的块注释可以嵌套。就是说,你可以这样注释:

/**
 * hhhh
 * /**
 *  fff
 *  /**
 *    ggggg
 *  */
 * */
 *
 * abc
 *
 */
fun main(args:Array<String>){
    val f = Functions()
    println(f.fvoid1())
    println(f.fvoid2())
    println(f.sum1(1,1))
    println(f.sum2(1,1))
}

main函数

Kotlin 程序的入口是名为"main"的函数。命令行参数通过这个方法的数组参数传递。

代码示例:

fun main(args: Array<String>) {}

变量声明

Kotlin声明变量可以用var或者 val
val声明的参数不能重新赋值(只读),但用var声明的可以(可写)。

代码示例:

    val fooVal = 10 // 不能再赋别的值给fooVal
    //fooVal = 11 // Val cannot be reassigned
    var fooVar = 10
    fooVar = 20 // fooVar可以重新赋值

其中,var fooVar = 10变量声明我们并没有指定变量的类型。

大部分情况下,Kotlin 可以判断变量的类型,所以不用每次都显式声明。
我们也可以像下面这样显式声明一个变量的类型:

    val foo: Int = 7

使用is 运算符进行类型检测

is 运算符检测一个表达式是否某类型的一个实例。

如果一个不可变的局部变量或属性已经判断出为某类型,那么检测后的分支中可以直接当作该类型使用,无需显式转换:

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj` 在该条件分支内自动转换成 `String`
        return obj.length
    }

    // 在离开类型检测分支后,`obj` 仍然是 `Any` 类型
    return null
}


fun main(args: Array<String>) {
    fun printLength(obj: Any) {
        println("'$obj' string length is ${getStringLength(obj) ?: "... err, not a string"} ")
    }
    printLength("Incomprehensibilities")
    printLength(1000)
    printLength(listOf(Any()))
}

或者

fun getStringLength(obj: Any): Int? {
    if (obj !is String) return null

    // `obj` 在这一分支自动转换为 `String`
    return obj.length
}


fun main(args: Array<String>) {
    fun printLength(obj: Any) {
        println("'$obj' string length is ${getStringLength(obj) ?: "... err, not a string"} ")
    }
    printLength("Incomprehensibilities")
    printLength(1000)
    printLength(listOf(Any()))
}

或者

fun getStringLength(obj: Any): Int? {
    // `obj` 在 `&&` 右边自动转换成 `String` 类型
    if (obj is String && obj.length >= 0) {
        return obj.length
    }

    return null
}


fun main(args: Array<String>) {
    fun printLength(obj: Any) {
        println("'$obj' string length is ${getStringLength(obj) ?: "... err, is empty or not a string at all"} ")
    }
    printLength("Incomprehensibilities")
    printLength("")
    printLength(1000)
}

字符串

原始字符串(raw string)由三重引号(""")分隔(这个跟python一样)。原始字符串可以包含换行符和任何其他字符。

    val fooRawString = """
fun helloWorld(val name : String) {
   println("Hello, world!")
}
"""
    println(fooRawString)

字符串可以包含模板表达式。模板表达式以美元符号($)开始。

    val fooTemplateString = "$fooString has ${fooString.length} characters"
    println(fooTemplateString)

if表达式

/**
 * `if` is an expression, i.e. it returns a value.
 * Therefore there is no ternary operator (condition ? then : else),
 * because ordinary `if` works fine in this role.
 * See http://kotlinlang.org/docs/reference/control-flow.html#if-expression
 */
fun main(args: Array<String>) {
    println(max(args[0].toInt(), args[1].toInt()))
}

fun max(a: Int, b: Int) = if (a > b) a else b

另外,在Kotlin中没有类似true? 1: 0这样的三元表达式。对应的写法是使用if else语句:

if(true) 1 else 0

when表达式

when表达式类似于Java中的switch。 代码示例:

fun cases(obj: Any) {
    when (obj) {
        1 -> print("第一项")
        "hello" -> print("这个是字符串hello")
        is Long -> print("这是一个Long类型数据")
        !is String -> print("这不是String类型的数据")
        else -> print("else类似于Java中的default")
    }
}



空对象检查Null Check

fun Any?.toString(): String

要使变量保持为null,必须将其显式指定为可空: 在变量类型后面加上? 符号,即声明为可空。

?. 运算符来访问一个可空的变量。
?: 运算符来指定当该变量为空时的替代值

代码示例:


package com.easy.kotlin

/**
 * Created by jack on 2017/5/30.
 */

fun main(args: Array<String>) {
    val s: String? = null
    println(s?.length)

    var fooNullable: String? = "abc"
    println(fooNullable?.length) // => 3
    println(fooNullable?.length ?: -1) // => 3
    fooNullable = null
    println(fooNullable?.length) // => null
    println(fooNullable?.length ?: -1) // => -1

    testNullSafeOperator(null)
    testNullSafeOperator("12345678901")
    testNullSafeOperator("123")

}


fun testNullSafeOperator(string: String?) {
    println(string?.toCharArray()?.getOrNull(10)?.hashCode())
}

fun toString(any:Any): String{
  return any?.toString()
}


这个null check是怎样实现的呢?

我们来看一下Kotlin ByteCode。打开IDEA->Tool->Kotlin->Show Kotlin ByteCode:

我们可以看到上面的Kotlin源码对应的字节码如下:

// ================com/easy/kotlin/NullCheckKt.class =================
// class version 50.0 (50)
// access flags 0x31
public final class com/easy/kotlin/NullCheckKt {


  // access flags 0x19
  public final static main([Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
    ACONST_NULL
    CHECKCAST java/lang/String
    ASTORE 1
   L0
    ALOAD 1
    ASTORE 2
   L1
    ALOAD 2
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L2
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L3
   L2
    ALOAD 2
    INVOKEVIRTUAL java/lang/String.length ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L3
    INVOKESTATIC kotlin/io/ConsoleKt.println (Ljava/lang/Object;)V
    LDC "abc"
    ASTORE 2
   L4
    ALOAD 2
    ASTORE 3
   L5
    ALOAD 3
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L6
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L7
   L6
    ALOAD 3
    INVOKEVIRTUAL java/lang/String.length ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L7
    INVOKESTATIC kotlin/io/ConsoleKt.println (Ljava/lang/Object;)V
    ALOAD 2
    ASTORE 4
   L8
    ALOAD 4
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L9
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L10
   L9
    ALOAD 4
    INVOKEVIRTUAL java/lang/String.length ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L10
    ASTORE 3
   L11
    ALOAD 3
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L12
    ICONST_M1
    GOTO L13
   L12
    ALOAD 3
    INVOKEVIRTUAL java/lang/Number.intValue ()I
   L13
    INVOKESTATIC kotlin/io/ConsoleKt.println (I)V
    ACONST_NULL
    CHECKCAST java/lang/String
    ASTORE 2
    ALOAD 2
    ASTORE 3
   L14
    ALOAD 3
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L15
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L16
   L15
    ALOAD 3
    INVOKEVIRTUAL java/lang/String.length ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L16
    INVOKESTATIC kotlin/io/ConsoleKt.println (Ljava/lang/Object;)V
    ALOAD 2
    ASTORE 4
   L17
    ALOAD 4
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L18
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L19
   L18
    ALOAD 4
    INVOKEVIRTUAL java/lang/String.length ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L19
    ASTORE 3
   L20
    ALOAD 3
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L21
    ICONST_M1
    GOTO L22
   L21
    ALOAD 3
    INVOKEVIRTUAL java/lang/Number.intValue ()I
   L22
    INVOKESTATIC kotlin/io/ConsoleKt.println (I)V
    ACONST_NULL
    CHECKCAST java/lang/String
    INVOKESTATIC com/easy/kotlin/NullCheckKt.testNullSafeOperator (Ljava/lang/String;)V
    LDC "12345678901"
    INVOKESTATIC com/easy/kotlin/NullCheckKt.testNullSafeOperator (Ljava/lang/String;)V
    LDC "123"
    INVOKESTATIC com/easy/kotlin/NullCheckKt.testNullSafeOperator (Ljava/lang/String;)V
    RETURN
   L23
    LOCALVARIABLE tmp0_safe_receiver Ljava/lang/String; L1 L3 2
    LOCALVARIABLE tmp1_safe_receiver Ljava/lang/String; L5 L7 3
    LOCALVARIABLE tmp2_safe_receiver Ljava/lang/String; L8 L10 4
    LOCALVARIABLE tmp3_elvis_lhs Ljava/lang/Integer; L11 L13 3
    LOCALVARIABLE tmp4_safe_receiver Ljava/lang/String; L14 L16 3
    LOCALVARIABLE tmp5_safe_receiver Ljava/lang/String; L17 L19 4
    LOCALVARIABLE tmp6_elvis_lhs Ljava/lang/Integer; L20 L22 3
    LOCALVARIABLE s Ljava/lang/String; L0 L23 1
    LOCALVARIABLE fooNullable Ljava/lang/String; L4 L23 2
    MAXSTACK = 2
    MAXLOCALS = 5

  // access flags 0x19
  public final static testNullSafeOperator(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0
    ALOAD 0
    ASTORE 3
   L0
    ALOAD 3
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L1
    ACONST_NULL
    CHECKCAST [C
    GOTO L2
   L1
    ALOAD 3
    INVOKESTATIC kotlin/text/StringsKt.toCharArray (Ljava/lang/String;)[C
   L2
    ASTORE 2
   L3
    ALOAD 2
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L4
    ACONST_NULL
    CHECKCAST java/lang/Character
    GOTO L5
   L4
    ALOAD 2
    BIPUSH 10
    INVOKESTATIC kotlin/collections/ArraysKt.getOrNull ([CI)Ljava/lang/Character;
   L5
    ASTORE 1
   L6
    ALOAD 1
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L7
    ACONST_NULL
    CHECKCAST java/lang/Integer
    GOTO L8
   L7
    ALOAD 1
    INVOKEVIRTUAL java/lang/Object.hashCode ()I
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   L8
    INVOKESTATIC kotlin/io/ConsoleKt.println (Ljava/lang/Object;)V
    RETURN
   L9
    LOCALVARIABLE tmp0_safe_receiver Ljava/lang/String; L0 L2 3
    LOCALVARIABLE tmp1_safe_receiver [C L3 L5 2
    LOCALVARIABLE tmp2_safe_receiver Ljava/lang/Character; L6 L8 1
    MAXSTACK = 2
    MAXLOCALS = 4

  // access flags 0x19
  public final static toString(Ljava/lang/Object;)Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
    ALOAD 0
    ASTORE 1
   L0
    ALOAD 1
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L1
    ACONST_NULL
    CHECKCAST java/lang/String
    GOTO L2
   L1
    ALOAD 1
    INVOKEVIRTUAL java/lang/Object.toString ()Ljava/lang/String;
   L2
    ARETURN
   L3
   L4
    LOCALVARIABLE tmp0_safe_receiver Ljava/lang/Object; L0 L2 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x19
  public final static <clinit>()V
    RETURN
   L0
    MAXSTACK = 0
    MAXLOCALS = 0
}



我们来单独看一下fun toString()的bytecode:

public final static toString(Ljava/lang/Object;)Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
    ALOAD 0
    ASTORE 1
   L0
    ALOAD 1
    ACONST_NULL
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
    IFEQ L1
    ACONST_NULL
    CHECKCAST java/lang/String
    GOTO L2

...

其中, ACONST_NULL 指令是把null压到栈顶。然后调用

INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z

这里的kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)函数代码是:


    public static boolean areEqual(Object first, Object second) {
        return first == null ? second == null : first.equals(second);
    }

反编译成Java代码,如下:

   @NotNull
   public static final String toString(@NotNull Object any) {
      Intrinsics.checkParameterIsNotNull(any, "any");
      return any != null?any.toString():null;
   }

由字节码分析可见,其实所谓的空指针安全操作符, 其实就是在内部封装了判空逻辑,来确保不出现空指针。

循环

while循环:

/**
 * `while` and `do..while` work as usual.
 * See http://kotlinlang.org/docs/reference/control-flow.html#while-loops
 */
fun main(args: Array<String>) {
    var i = 0
    while (i < args.size)
        println(args[i++])
}

for循环


/**
 * For loop iterates through anything that provides an iterator.
 * See http://kotlinlang.org/docs/reference/control-flow.html#for-loops
 */
fun main(args: Array<String>) {
    for (arg in args)
        println(arg)
    // or
    println()
    for (i in args.indices)
        println(args[i])
}

枚举


enum class Color(
        val r: Int, val g: Int, val b: Int
) {
    RED(255, 0, 0), ORANGE(255, 165, 0),
    YELLOW(255, 255, 0), GREEN(0, 255, 0), BLUE(0, 0, 255),
    INDIGO(75, 0, 130), VIOLET(238, 130, 238);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun main(args: Array<String>) {
    println(Color.BLUE.rgb())
}


enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

fun getMnemonic(color: Color) =
    when (color) {
        Color.RED -> "Richard"
        Color.ORANGE -> "Of"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        Color.INDIGO -> "In"
        Color.VIOLET -> "Vain"
    }

fun main(args: Array<String>) {
    println(getMnemonic(Color.BLUE))
}

遍历Map


/**
 *  Kotlin Standard Library provide component functions for Map.Entry
 */

fun main(args: Array<String>) {
    val map = hashMapOf<String, Int>()
    map.put("one", 1)
    map.put("two", 2)

    for ((key, value) in map) {
        println("key = $key, value = $value")
    }
}

拼接字符串

fun <T> joinToString(
        collection: Collection<T>,
        separator: String,
        prefix: String,
        postfix: String
): String {

    val result = StringBuilder(prefix)

    for ((index, element) in collection.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(element)
    }

    result.append(postfix)
    return result.toString()
}

fun main(args: Array<String>) {
    val list = listOf(1, 2, 3)
    println(joinToString(list, "; ", "(", ")"))
}


集合类操作

Kotlin的集合类有可变集合和不可变集合(lists、sets、maps 等)。精确控制集合的编辑权限,有助于消除 bug 和设计良好的 API。

预先了解一个可变集合的只读视图和一个真正的不可变集合之间的区别是很重要的。

Kotlin 的 List<out T> 类型是一个提供只读操作如 sizeget等的接口。和 Java 类似,它继承自 Collection<T> 进而继承自 Iterable<T>

而改变 list 的方法是由 MutableList<T> 加入的。这一模式同样适用于 Set<out T>/MutableSet<T>Map<K, out V>/MutableMap<K, V>

我们可以看下 list 及 set 类型的基本用法:

val numbers: MutableList<Int> = mutableListOf(1, 2, 3)
val readOnlyView: List<Int> = numbers
println(numbers)        // 输出 "[1, 2, 3]"
numbers.add(4)
println(readOnlyView)   // 输出 "[1, 2, 3, 4]"
readOnlyView.clear()    // -> 不能编译

val strings = hashSetOf("a", "b", "c", "c")
assert(strings.size == 3)



fun kotlin(ktFile: String): MutableList<String> {
        val result = mutableListOf<String>()

        kotlinc(ktFile)

        val ktClass = " " + ktFile.substring(0, ktFile.indexOf(".kt")) + "Kt"
        println(ktClass)
        val kotlin = KotlinBin.KOTLIN.binPath + ktClass
        println(kotlin)
        val runtime: Runtime = Runtime.getRuntime()
        val process: Process = runtime.exec(kotlin)
        val exitValue = process.waitFor()
        if (exitValue != 0) {
            println("exit with $exitValue")
            result.add("exit with $exitValue")
            return result
        }

        process.inputStream.bufferedReader().lines().forEach {
            println(it)
            result.add(it)
        }
        return result
    }



我们使用

val numbers: MutableList<Int> = mutableListOf(1, 2, 3)

创建一个初始化元素1,2,3的元素类型为Int的MutableList<Int>可变List。

使用

val result = mutableListOf<String>()

创建一个空的MutableList<String>元素类型为String的可变List。

Kotlin 没有专门的语法结构创建 list 或 set。 要用标准库的方法,如
listOf()mutableListOf()setOf()mutableSetOf()
在非性能关键代码中创建 map 可以用一个简单的惯用法来完成:mapOf(a to b, c to d)

注意上面的 readOnlyView 变量(译者注:与对应可变集合变量 numbers)指向相同的底层 list 并会随之改变。 如果一个 list 只存在只读引用,我们可以考虑该集合完全不可变。创建一个这样的集合的一个简单方式如下:

val items = listOf(1, 2, 3)

目前 listOf 方法是使用 array list 实现的,但是未来可以利用它们知道自己不能变的事实,返回更节约内存的完全不可变的集合类型。

注意这些类型是协变的。这意味着,你可以把一个 List<Rectangle> 赋值给 List<Shape> 假定 Rectangle 继承自 Shape。对于可变集合类型这是不允许的,因为这将导致运行时故障。

有时你想给调用者返回一个集合在某个特定时间的一个快照, 一个保证不会变的:

class Controller {
    private val _items = mutableListOf<String>()
    val items: List<String> get() = _items.toList()
}

这个 toList 扩展方法只是复制列表项,因此返回的 list 保证永远不会改变。

List 和 set 有很多有用的扩展方法值得熟悉:

val items = listOf(1, 2, 3, 4)
items.first() == 1
items.last() == 4
items.filter { it % 2 == 0 }   // 返回 [2, 4]

val rwList = mutableListOf(1, 2, 3)
rwList.requireNoNulls()        // 返回 [1, 2, 3]
if (rwList.none { it > 6 }) println("No items above 6")  // 输出“No items above 6”
val item = rwList.firstOrNull()

…… 以及所有你所期望的实用工具,例如 sort、zip、fold、reduce 等等。

Map 遵循同样模式。它们可以容易地实例化和访问,像这样:

val readWriteMap = hashMapOf("foo" to 1, "bar" to 2)
println(readWriteMap["foo"])  // 输出“1”
val snapshot: Map<String, Int> = HashMap(readWriteMap)

小结

本章示例代码:https://github.com/EasyKotlin/easykotlin

参考资料

1.http://kotlinlang.org/docs/reference/grammar.html


Kotlin开发者社区

专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。

High availability, high performance, high real-time large-scale distributed system architecture design

分布式框架:Zookeeper、分布式中间件框架等
分布式存储:GridFS、FastDFS、TFS、MemCache、redis等
分布式数据库:Cobar、tddl、Amoeba、Mycat
云计算、大数据、AI算法
虚拟化、云原生技术
分布式计算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信机制:Dubbo、RPC调用、共享远程数据、消息队列等
消息队列MQ:Kafka、MetaQ,RocketMQ
怎样打造高可用系统:基于硬件、软件中间件、系统架构等一些典型方案的实现:HAProxy、基于Corosync+Pacemaker的高可用集群套件中间件系统
Mycat架构分布式演进
大数据Join背后的难题:数据、网络、内存和计算能力的矛盾和调和
Java分布式系统中的高性能难题:AIO,NIO,Netty还是自己开发框架?
高性能事件派发机制:线程池模型、Disruptor模型等等。。。

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。不积跬步,无以至千里;不积小流,无以成江河。

Kotlin 简介

Kotlin是一门非研究性的语言,它是一门非常务实的工业级编程语言,它的使命就是帮助程序员们解决实际工程实践中的问题。使用Kotlin 让 Java程序员们的生活变得更好,Java中的那些空指针错误,浪费时间的冗长的样板代码,啰嗦的语法限制等等,在Kotlin中统统消失。Kotlin 简单务实,语法简洁而强大,安全且表达力强,极富生产力。

Java诞生于1995年,至今已有23年历史。当前最新版本是 Java 9。在 JVM 生态不断发展繁荣的过程中,也诞生了Scala、Groovy、Clojure 等兄弟语言。

Kotlin 也正是 JVM 家族中的优秀一员。Kotlin是一种现代语言(版本1.0于2016年2月发布)。它最初的目的是像Scala那样,优化Java语言的缺陷,提供更加简单实用的编程语言特性,并且解决了性能上的问题,比如编译时间。 JetBrains在这些方面做得非常出色。

Kotlin语言的特性

用 Java 开发多年以后,能够尝试一些新的东西真是太棒了。如果您是 Java 开发人员,使用 Kotlin 将会非常自然流畅。如果你是一个Swift开发者,你将会感到似曾相识,比如可空性(Nullability)。 Kotlin语言的特性有:

1.简洁

大幅减少样板代码量。

2.与Java的100%互操作性

Kotlin可以直接与Java类交互,反之亦然。这个特性使得我们可以直接重用我们的代码库,并将其迁移到 Kotlin中。由于Java的互操作性几乎无处不在。我们可以直接访问平台API以及现有的代码库,同时仍然享受和使用 Kotlin 的所有强大的现代语言功能。

3.扩展函数

Kotlin 类似于 C# 和 Gosu, 它提供了为现有类提供新功能扩展的能力,而不必从该类继承或使用任何类型的设计模式 (如装饰器模式)。

4.函数式编程

Kotlin 语言一等支持函数式编程,就像Scala一样。具备高阶函数、Lambda 表达式等函数式基本特性。

5.默认和命名参数

在Kotlin中,您可以为函数中的参数设置一个默认值,并给每个参数一个名称。这有助于编写易读的代码。

6.强大的开发工具支持

而由于是JetBrains出品,我们拥有很棒的IDE支持。虽然Java到Kotlin的自动转换并不是100% OK 的,但它确实是一个非常好的工具。使用 IDEA 的工具转换Java代码为 Kotlin 代码时,可以轻松地重用60%-70%的结果代码,而且修改成本很小。

Kotlin 除了简洁强大的语法特性外,还有实用性非常强的API以及围绕它构建的生态系统。例如:集合类 API、IO 扩展类、反射API 等。同时 Kotlin 社区也提供了丰富的文档和大量的学习资料,还有在线REPL。

A modern programming language that makes developers happier. Open source forever

图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)
图来自《Kotlin从入门到进阶实战》 (陈光剑,清华大学出版社)

https://kotlinlang.org/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容