Kotlin 实战笔记
Kotlin 的集合分为可变集合和不可变集合,不可变集合类似 Java 中的 List、Set、Map,而可变集合如 MutableList
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 定义的可变参数,使用方式还是和以前一样的。