转载

《Kotlin 实战》第3章笔记

Kotlin 实战笔记

集合

Kotlin 的集合分为可变集合和不可变集合,不可变集合类似 Java 中的 List、Set、Map,而可变集合如 MutableList 、MutableSet 、MutableMap

val set1 = setOf(1, 2, 3)
val set2 = hashSetOf(1, 2, 3)
val set3 = mutableSetOf(1, 2, 3)

val list1 = listOf(1, 2, 3)
val list2 = arrayListOf(1, 2, 3)
val list3 = mutableListOf(1, 2, 3)

val map1 = mapOf(1 to "one", 2 to "two", 3 to "three")
val map2 = hashMapOf(1 to "one", 2 to "two", 3 to "fifty-three")
val map3 = mutableMapOf(1 to "one", 2 to "two", 3 to "three")

默认参数值

Kotlin 中声明的函数可以指定默认的参数值:

fun <T>joinToString(
    collection: Collection<T>,
    //下面三个参数都有默认值
    separator: String = "",
    prefix: String = "",
    postfix: String = ""
) {}

fun main(args:Array<String>) {
    val list = listOf(1, 2, 3)

    //有默认值的参数可以不传值
    joinToString(list)
    joinToString(list, "")
    joinToString(list, "", "")
    joinToString(list, "", "", "")
}

上面这个例子中 joinToString(list, "", "", "") 的调用可以做得更优雅:

//调用时标明参数的名称
joinToString(list, separator = "", prefix = "", postfix = "")

注意:在调用一个函数时,如果指定了一个参数名称,那么之后的所有参数都需要标明名称:

//正确示例
joinToString(list, "", prefix = "", postfix = "")

//错误示例
joinToString(list, separator = "", "", postfix = "")

顶层函数和属性

在 Kotlin 中可以直接在一个 Kotlin 文件声明函数和属性,不必像 Java 那样必须在类中才能声明属性和方法。

//文件名:KotlinTest.kt
package com.itscoder.ljuns.practise.kotlin.chapter3
//类似于 Java 中 private static final test1 = 0;
val test1: Int = 0
//类似于 Java 中 public static final test2 = 0;
const val test2: Int = 0
//类似于 Java 中 private static int test3;
var test3: Int = 0
//类似于 Java 中 public static final void test() {}
fun test() {}

看看编译后生成的文件:

//类名就是文件名
public final class KotlinTestKt{
   private static final int test1 = 0;
   public static final int test2 = 0;
   private static int test3;

   public static final int getTest1() {
      return test1;
   }

   public static final int getTest3() {
      return test3;
   }

   public static final void setTest3(int var0) {
      test3 = var0;
   }

   public static final void test() {
   }
}

拓展函数和属性

拓展函数

Kotlin 可以在不修改源代码的情况下给原有的类添加函数,即拓展函数。

新建一个 kotlin 文件 StringUtil.kt:

/**
 * 给 String 类拓展了一个 lastChar() 的函数,拓展函数名可以和成员函数名相同
 * String:接收者类型,即要拓展的类或接口
 * this:接收者对象,可省略
 */
fun String.lastChar(): Char = this.get(this.length - 1)
// 省略 this
fun String.lastChar(): Char = get(length - 1)

上面代码给 String 这个类拓展了一个返回最后一个字符的函数,用法和其他普通函数一样:

print("Kotlin".lastChar())

编译后生成的 Java 文件:

public final class StringUtilKt{
   public static final char lastChar(@NotNull String $receiver){
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      return $receiver.charAt($receiver.length() - 1);
   }
}

所以,如果是在 Java 中调用的话就是这样:

System.out.println(StringUtilKt.lastChar("Java"));

此外,拓展函数不能被重写,举个例子:

open class View{
    open fun click() = println("view click")
}
// 继承 View
open class Button:View() {
    // 重写 click()
    override fun click() = println("button click")
}

// 分别有拓展函数
fun View.showOff() = println("I`m a View")
fun Button.showOff() = println("I`m a Button")

fun main(args:Array<String>) {
    val view: View = Button()

    view.click() // 打印结果:button click
    // 调用拓展函数时变量类型由静态类型决定,即 View
    view.showOff() // 打印结果:I`m a View
    View().showOff() // 打印结果:I`m a View
    Button().showOff() // 打印结果:I`m a Button
}

注意:如果一个类的成员函数和拓展函数有相同的函数名,成员函数会被优先使用

拓展属性

和拓展属性类似,可以给已存在的类添加拓展属性。

在拓展函数的例子中添加拓展属性:

/**
 * 给 String 类拓展了一个 lastChar 的属性,拓展属性名可以和成员属性名相同
 * 必须提供对应的 gettr()、setter() 方法
 */
val String.lastChar: Char
    get() = get(length - 1)

可变参数

Kotlin 中可变参数的定义和使用与 Java 有点不同:

// 用 vararg 来声明可变参数
fun test(vararg value: String) = println(value.size)

fun main(args:Array<String>) {
    // 这种调用和 Java 中一样
	test("one", "two", "three")
    // Kotlin 不允许传入一个数组,要加一个特殊符号 *
    test(*args)
}

看看编译后的文件:

public static final void test(@NotNull String... value){
      Intrinsics.checkParameterIsNotNull(value, "value");
      int var1 = value.length;
      System.out.println(var1);
   }

   public static final void main(@NotNull String[] args){
      Intrinsics.checkParameterIsNotNull(args, "args");
      test("one", "two", "three");
      test((String[])Arrays.copyOf(args, args.length));
   }

所以如果在 Java 中去调用 Kotlin 定义的可变参数,使用方式还是和以前一样的。

原文  https://ljuns.itscoder.com/2018/10/27/《Kotlin 实战》第3章笔记/
正文到此结束
Loading...