val a: Int = 123 val sumLambda: (Int, Int) -> Int = { x, y -> x + y }
publicfunmain(args: Array<String>): Unit {} publicfunmain(args: Array<String>) {} funmain(args: Array<String>) {}
函数的定义和类型声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funsum(a: Int, b: Int): Int { return a + b } // 返回类型自动推断(函数单一表达式) funsum(a: Int, b: Int) = a + b // single expression
// 无返回值,声明 Unit 类型(类似 Java 和 TS 的 void) funprintSum(a: Int, b: Int): Unit { println(a + b) }
// public 必须明确声明返回值类型 publicfunsum(a: Int, b: Int): Int = a + b
// 返回值是 Unit 类型,则可以省略 publicfunprintSum(a: Int, b: Int) { print(a + b) }
函数的调用
1 2 3 4 5 6 7 8 9 10 11
funsum(a: Int, b: Int, c: Int):Int { println("a = $a,b = $b,c = $c") return a + b + c }
sum(0, 1, 2) // a = 0, b = 1, c = 2 sum(a = 0, b = 1, 2) // a = 0, b = 1, c = 2 sum(a = 0, 1, c = 2) // a = 0, b = 1, c = 2 sum(0, b = 1, c = 2) // a = 0, b = 1, c = 2 sum(c = 2, b = 1, a = 0) // a = 0, b = 1, c = 2 sum(c = 0, b = 1, 2) // Error
:: 操作符
1 2 3 4 5 6 7 8 9 10 11 12 13
classPerson(val nickName: String) { funfoo(a: Int): Int { println("$a") return a }
val p = Persion("musk") p.getFun(10, p::foo) // 10
可增参数(可变长参数函数)
1 2 3 4 5
funvars(vararg v: Int){ for(vi in v) println(vi) }
vars(1,2,3,4) // 1234
Lambda(匿名函数 \ 闭包表达式)
1 2 3 4 5 6 7 8 9 10 11
funmain(args: Array<String>) { val sumLambda: (Int, Int) -> Int = { x, y -> x + y } println(sumLambda(1, 2)) }
val sumLambda: (Int, Int) -> Int = { x, y -> x + y } funmain(args: Array<String>) { println(sumLambda(1, 2)) }
// Named arguments are not allowed for function types
定义常量和变量
1 2 3 4 5 6 7 8 9 10
// 变量 var <标识符>: <类型><可选> = <初始化知> val name: String name = "xx" name = "yalda"// Val cannot be reassigned // 常量与变量都可以没有初始化值,但是在引用前必须初始化
// 常量 val <标识符>: <类型><可选> = <初始化知> var age: Int = 1 var age1: Int// 声明时未初始化,必须声明类型 var age = 0// 编译器支持自动类型判断
注释
1 2 3 4 5 6 7
// single row command /* multiple row commands */ /* multiple row commands /* kotlin support nest commands*/ */
字符串模板
1 2 3 4
val str: String = "single string" val temp: String = "$str" val temp2: Strig = "$str length is ${str.length}"
Null 检查机制
1 2 3 4 5
var age: String? = "23"// ? means optional
var age = age!!.toInt() // 23 or null-point-exceptions val age1 = age?.toInt() // 23 or null val age2 = age?.toInt() ?: -1// 23
类型检测&自动类型转换
1 2 3 4 5 6 7 8
fungetStringLength(obj: Any): Int? { if (obj is String) return obj.length if (obj !is String) returnnull// or
if (obj is String && obj.length > 0) return obj.length //
return nulll }
区间(Range)
由 .. 的 rangeTo 函数 & in & ~!in 形成
1 2 3 4 5
for (i in1..4) print(i) // [1, 4] for (i in1 until 4) print(n) // [1, 4) for (i in4..1) print(i) // for (i in1..4 step 2) print(i) // 13 for (i in4 downTo 1) print(i) // 4321
基本数据类型
基本数值
Byte \ Short \ Int \ Long Float \ Double
字面常量
1 2 3 4 5 6
val oneMillion = 1_000_000 val ID = 321023_1999_1212_0000L val bigD = 123.5e10 val f= 123213f// 123213F 123213.0 val hexBytes = 0xCCCCCC// 13421772 val bytes = 0b111111_00000000_111111_000000// 66064320
比较
1 2 3 4 5 6 7 8 9
val a: Int = 123 a == 123// true a === 123// true val b: Int = 123 a == b // true a === b // true val c: Int? = a a == c // true a === c // false
1 2 3 4 5 6 7 8 9 10 11
// 发现一个有趣的现象 val a: Int = 127 val c: Int? = a val d: Int? = a c === d // true
val b: Int = 128 val c1: Int? = b val d1: Int? = b c1 === d1 // false // 个人怀疑,kotlin 对代码做了优化;小于 2^8 时使用数值对象,超过则创建新对象
类型转换
较小的类型不是较大类型的子类型;在不进行显式转换下是违法的
1 2 3 4 5 6
val b: Byte = 1 val i: Int = b // error val i: Int = b.toInt()
// 有些情况会做自动类型转化 val l = 1L + 3// Long + Int -> Long
1 2 3 4 5 6 7
toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double toChar(): Char
val c: Char = 'c'// 必须是单引号 val c: Char = '\u2354'// \t \n \b \r \' \" \\ \$
if(c !in'0'..'9') // range
布尔 Boolean
1 2 3 4
val b: Boolean = false// false or true false || true// true false && true// false !false// true
数组
由类 Array 实现,拥有 size \ get \ set 方法;Kotlin 中的数组是不协变的(invariant); 创建方式:1、arrayOf() 2、工厂函数
1 2 3 4 5 6 7 8 9 10
// [1,2,3] arrayOf 函数 val a = arrayOf(1, 2, 3) a[0] a[0] = 1
// [2,4,6] array 工厂函数 val a1: Array = Array(3, { x -> x * 2 }) val ia: IntArray = intArrayOf(1,2,3) val ba: ByteArray = byteArrayOf(1,2,3) val sa: ShortArray = shortArrayOf(1,2,3)
字符串
同 Java 一样 String 是不可变的
1 2 3 4 5 6 7 8 9 10
for (c in"str") println(c)
val text = """ |multiple str1 |multiple str2 |multiple str3 """ text // some pre space(include |) text.trimMargin() // default use | for replace pre space text.trimMargin(">") // use > for replace pre space
字符串模板
1 2 3 4 5
val i = "10" val s = "len = ${i.length}"// len = 2 val ms = """ |price is $$i """// price is $10
条件控制
Kotlin 里的 if 和 when 均可以作为条件控制语句,也可以作为表达式
IF 表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// condition is a statement return Boolean; ex. i in 1..8 if (condition) ..
var max = a if (a < b) max = b if (a < b) max = 2else max = 1 if (a < b) { max = b }
// 作为表达式返回结果 val max = if (a > b) a else b // Kotlin 没有三元表达式 val max = if (a > b) { println("Choose a value") a } else { println("$b") b }
// 作为表达式使用时,符合的分支的值就是表达式的值 // 也可以作为语句(条件控制语句)使用 when (x) { 1 -> println("11") 2 -> println("22") 3, 4 -> println("3344") in5..10 -> println("5 to 10") !in11..20 -> println("no in 11 to 20") else -> { println("default") } }
// use is or !is funhasPrefix(x: Any) = when(x) { // Any 是 Kotlin 所有类的基类 is String -> println("is String") isInt -> println("is Int") else -> { println("else") } }
// replace if-elseif chain fun String.isInTen() = thisin"1".."10" fun String.isInHundred() = thisin"1".."100" var a = "50" when { a.isInTen() -> println("a in [1, 10]") a.isInHundred() -> println("a in [1, 100]") else -> println("a not in range") }
// use in val items = setOf("apple", "huawei") when { "xiaomi"in items -> println("mi") "vivo"in items -> println("mi") }
// array & array.indices & array.withIndex() for (v in arrayOf(1,2,3)) print(v) // 123 for (i in arrayOf(1,2,3).indices) print(i) // 012 for (v in Array(3, { x -> x * 2 })) print(v) // 024 for ((i,v) in arrayOf(1,2,4).withIndex()) println("$i$v")
// list & & list.indices list.withIndex() for (v in listOf(1,2,3)) print(v) // 123 for(i in listOf(1,2,3).indices) print("$i") // 012 for ((index, value) in listOf(1,2,3).withIndex()) println(v)
// set & set.withIndex() for (v in setOf("aa", "bb")) println("$v") for ((i, v) in setOf("aa", "bb").withIndex()) println("$i$v")
// map & map destruct for (v in mapOf("a" to "xx", "b" to "yy")) println(v) // a=xx \n b =yy for ((k, v) in mapOf("a" to "xx", "b" to "yy")) println("$k$v") // a xx \n b yy
// range for (v in1..10) print("$v") // 12345678910 for (v in1 until 10) print(v) // 123456789 for (v in1..10 step 2) print(v) // 13579 for (v in10 downTo 1) print(v) // 10987654321
while & do…while 循环
1 2
while ( /* Boolean expression */) {} do { /* logic */ } while ( /* Boolean expression */)
返回和跳转
return 从循环体的包装函数 & Lambda 返回
break 终止循环体
continue 跳出本次循环,进入下一次循环
1 2 3 4 5 6
while(i < 10) { i += 1 if (i == 2) continue if (i ==5 ) break print(i) } // 134
fun Student.learn() { study() // class Student(扩展接受者优先) this@Classmeta.study() // Classmeta.study } funcaller(s: Student) = s.learn() } val s = Student() val m = Classmeta() m.caller(s) // day day up \n meta study
// object Student { var name = "yalda" object ClassRoom { val position = "L4" funshowName() = println("$name@N24432") } } val s = Student s.ClassRooo.position //'ClassRoom' accessed via instance refer Student.ClassRoom.showName() // yalda@N24432