Kotlin初探
本文于
1290
天之前发表,文中内容可能已经过时。
[TOC]
概述 以.kt结尾的程序文件
优点:
简洁:大大减少样板代码的数量
安全:避免空指针异常等整个类的错误
互操作性:充分利用JVM、Android和游览器的现有库
工具友好:可用任何Java IDE或者使用命令行构建
创建方法 1 2 3 4 5 6 7 8 9 fun sum (a: Int , b: Int ) : Int { return a + b } fun sum2 (a: Int , b: Int ) : Int = a + b
可变长参数函数(vararg) 1 2 3 4 5 6 7 8 9 10 11 fun vars (vararg v:Int ) { for (vt in v){ print("----$vt " ) } } main : vars(1 ,2 ,3 ,4 ,5 )
lambda 1 2 val sumLambda:(Int ,Int ) -> Int = {a,b ->a+b}println(sumLambda(1 ,2 ))
val 1 2 val <标识符> :<类型> = <初始化值>
var 1 2 var <标识符> :<类型> = <初始化值>
1 2 3 4 5 6 7 8 val a: Int = 1 val b = 1 val c: Int c = 1 var x = 5 x += 1
注释
字符串模版 $ 表示一个变量名或者变量值 $varName 表示变量值 ${varName.fun()} 表示变量的方法返回值:
1 2 3 4 5 6 7 var a = 1 val s1 = "a is $a " a = 2 val s2 = "${s1.replace("is" , "was" )} , but now is $a "
NULL检查机制 1 2 3 4 5 6 7 8 9 10 11 12 var age: String? = "23" val ages = age!!.toInt()val ages1 = age?.toInt()val ages2 = age?.toInt() ?: -1 fun parseInt (str: String ) : Int ? { }
类型检测及自动类型转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 fun getStringLength (obj: Any ) : Int ? { if (obj is String) { return obj.length } return null }
区间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 for (i in 1. .4 ) print(i) for (i in 4. .1 ) print(i) if (i in 1. .10 ) { println(i) } for (i in 1. .4 step 2 ) print(i) for (i in 4 downTo 1 step 2 ) print(i) for (i in 1 until 10 ) { println(i) }
基本数据类型
类型
位宽度
Double
64
Float
32
Long
64
Int
32
Short
16
Byte
8
十进制:123
长整型以大写的 L 结尾:123L
16 进制以 0x 开头:0x0F
2 进制以 0b 开头:0b00001011
Doubles 默认写法: 123.5
, 123.5e10
Floats 使用 f 或者 F 后缀:123.5f
注意:8进制不支持
可以使用下划线使数字常量更易读:
1 2 3 4 5 val oneMillion = 1_000_000 val creditCardNumber = 1234_5678_9012_3456L val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010
比较两个数字
Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。
三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小
类型转换 1 2 3 4 5 6 7 8 9 10 val b: Byte = 1 val i: Int = b.toInt() toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double toChar(): Char
位操作符 1 2 3 4 5 6 7 shl(bits) – 左移位 (Java’s <<) shr(bits) – 右移位 (Java’s >>) ushr(bits) – 无符号右移位 (Java’s >>>) and(bits) – 与 or(bits) – 或 xor(bits) – 异或 inv() – 反向
字符 Char:使用单引号'
包含起来的
布尔 Boolean:true和false
1 2 3 || – 短路逻辑或 && – 短路逻辑与 ! - 逻辑非
数组
注意: 与 Java 不同的是,Kotlin 中数组是不协变的(invariant)。
1 2 3 4 5 6 7 8 9 10 fun main (args: Array <String >) { val a = arrayOf(1 , 2 , 3 ) val b = Array(3 , { i -> (i * 2 ) }) println(a[0 ]) println(b[1 ]) }
除了类Array,还有ByteArray, ShortArray, IntArray,用来表示各个类型的数组,省去了装箱操作,因此效率更高,其用法同Array一样
字符串 和 Java 一样,String 是不可变的
1 2 3 for (c in str) { println(c) }
Kotlin 支持三个引号 “”” 扩起来的字符串,支持多行字符串,比如:
1 2 3 4 5 6 7 fun main (args: Array <String >) { val text = """ 多行字符串 多行字符串 """ println(text) }
String 可以通过 trimMargin() 方法来删除多余的空白。
1 2 3 4 5 6 7 8 9 10 fun main (args: Array <String >) { val text = """ |多行字符串 |菜鸟教程 |多行字符串 |Runoob """ .trimMargin() println(text) }
字符串模版表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 fun main (args: Array <String >) { val i = 10 val s = "i = $i " println(s) } fun main (args: Array <String >) { val s = "runoob" val str = "$s .length is ${s.length} " println(str) } fun main (args: Array <String >) { val price = """ ${'$' } 9.99 """ println(price) }
When表达式 类似于其他语言的switch,else类似于default
1 2 3 4 5 6 7 when (x) { 1 -> print("x == 1" ) 2 -> print("x == 2" ) else -> { print("x 不是 1 ,也不是 2" ) } }
类
主构造器中不能包含任何代码,初始化代码可以放在初始化代码段中,初始化代码段使用 init 关键字作为前缀。
类也可以有二级构造函数,需要加前缀 constructor
类默认是不可变的,即是被final修饰的,使用open后,去除final
内部类使用 inner 关键字来表示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 abstract final enum open annotation private protected public internal 模块: 一个 IntelliJ IDEA 模块; 一个 Maven 项目; 一个 Gradle 源集(例外是 test 源集可以访问 main 的 internal 声明); 一次 <kotlinc> Ant 任务执行所编译的一套文件。
扩展函数 1 2 3 4 5 6 7 8 9 10 11 class User (var name:String)fun User.Print () { print("用户名 $name " ) } fun main (arg:Array <String >) { var user = User("Runoob" ) user.Print() }
伴生对象 关键字整理
lateinit:延迟初始化
作用:具体来讲,这个关键字告诉编译器,我无法声明的时候就初始化,但是我保证我在使用前一定会初始化,你就别给我检查了。
apply:用于对象配置,类似于构造者模式(Builder),调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象
with:返回是最后一行,然后可以直接调用对象的方法,感觉像是let和apply的结合。
let:默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return
also:调用某对象的also函数,则该对象为函数的参数。在函数块内可以通过 it 指代该对象。返回值为该对象自己。
run:run函数和apply函数很像,只不过run函数是使用最后一行的返回,apply返回当前自己的对象。