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返回当前自己的对象。