Skip to content

Kotlin入门

Posted on:March 6, 2020 at 23:12:15 GMT+8

关键词语

var val

fun

a:Int

open override

constructor

Basic Syntax

Defining packages

package my.demo

import java.util.*
// as java

Defining functions

fun sum(a: Int, b: Int): Int {
    return a + b
}
fun sum(a: Int, b: Int) = a + b
// inferred return type
fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}
// return no meaningful value

fun printSum(a: Int, b: Int) {
    println("sum of $a and $b is ${a + b}")
}
// Unit can be omitted

Defining variables

val a: Int = 1
val b = 2 // type can be inferred

val c: Int
c = 3
// read-only local variables are defined using val
var x = 5 // Int type is inferred
x += 1
// variables can be reassigned use var

Comments

//

/*
	*/

/*
	/*
		*/
			*/
// block comments can be nested

Using string templates

var a = 1
val s1 = "a is $a"

a = 2
val s2 = "${s1.replace("is", "was")}, but now is $a"
// { }

Using conditional expressions

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}
fun maxOf(a: Int, b: Int) = if (a > b) a else b

Using nullable values and checking for null

fun parseInt(str: String): Int? {
    // return null if str is not a integer
    return str.toIntOrNull()
}
// Int?

fun printProduct(arg1: String, arg2: String) {
    val x = parseInt(arg1)
    val y = parseInt(arg2)

    //! x * y
    // Error: x y might be null

    if (x != null && y != null) {
        // x y automatically cast to non-nullable after null check
        println(x * y);
    }
    else {
        println("either '$arg1' or '$arg2 is not a number" )
    }
}
fun printProduct(arg1: String, arg2: String) {
// ...
    if (x != null && y != null) {
        // x y automatically cast to non-nullable after null check
        println(x * y);
    }
// ...

Using type checks and automatic casts

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        return obj.length
    }

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

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

    return null
}

Using a for loop

var items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
    println(item)
}
var items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
    println(items[index])
}

Using a while loop

var items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
    println(items[index])
    index++
}

Using when expression

fun describe(obj: Any): String =
	when(obj) {
    	1 -> "One"
    	"Hello" -> "Greeting"
    	is Long -> "Long"
    	!is String -> "Not a string"
   		in 1..10 -> print("obj is in the range")
        // else is required
    	else -> "Unknown"
	}

Using ranges

val x = 10
val y = 9
if (x in 1..y+1) {
    println("fits in range")
}
val list = listOf("a", "b", "c")

if (-1 !in 0..list.lastIndex) {
    println("-1 is out of range")
}
if (list.size !in list.indices) {
    println("list size is out of valid list indices range, too")
}
for (x in 1..5) {
    print(x)
}
for (x in 1..10 step 2) {
    print(x)
}
println()
for (x in 9 downTo 0 step 3) {
    print(x)
}
// step

Using collections

when {
    "orange" in items -> println("juicy")
    "apple" in items -> println("apple is fine too")
}

Creating basic classes and their instances

var rectangle = Rectangle(5.0, 2.0)
var triangle = Triangle(3.0, 4.0, 5.0)
// new is not required

数据类

data class Student (
	var name : String,
	var id : Int)

嵌套类与内部类

标记为 inner 的嵌套类可以访问其外部类的成员,内部类有一个对外部类的对象的引用。

Kotlin 中的匿名内部类访问的外部类的局部变量不需要声明为 final,如下:

fun main() {
    var i = 1
    foo2(object : Inner {
        override fun print() {
            i = 2
            println(i) // 2
        }
    })
    println(i) // 2
}

fun foo2(foo: Inner) {
    foo.print()
}

interface Inner {
    fun print()
}

是个语法糖,会被解糖为:

    public static final void main(@NotNull String[] args) {
      final IntRef i = new IntRef();
      i.element = 1;
      foo2((Inner)(new Inner() {
         public void print() {
            i.element = 2;
            int var1 = i.element;
            System.out.println(var1);
         }
      }));
      int var2 = i.element;
      System.out.println(var2);
   }

   public static final void foo2(@NotNull Inner foo) {
      Intrinsics.checkParameterIsNotNull(foo, "foo");
      foo.print();
   }

泛型

一个关键字实现单例

object Log {
    fun i(string: String) {
        println(string)
    }
}

fun main(args: Array<String>) {
    Log.i("test")
}

use

inline fun <T : Closeable?, R> T.use(block: (T) -> R): R

Executes the given block function on this resource and then closes it down correctly whether an exception is thrown or not.

用于实现了Closeable接口的类,执行闭包函数,然后关闭类,不管有没有异常。

参考

kotlin为什么匿名内部类的参数引用时不需要final? - 知乎

2020-3-6 23:12:57