Kotlin 学习笔记 整理


1、在 Kotlin 中类可以有属性,我们可以使用 :

 1.1、var 关键字声明可变属性:

 

var x = 5 // `Int` type is inferred
x += 1

 

 1.2、val 关键字声明只读属性:

val a: Int = 1  // 立刻赋值
val b = 2   // `Int` 类型是自推导的
val c: Int  // 没有初始化器时要指定类型
c = 3       // 推导型赋值


2、空安全
 2.1、"?" -> 声明为可空的变量  

var b: String? = "abc"
b = null


 2.2、"?." -> 如果 b 不为空则返回长度,否则返回空。这个表达式的的类型是 Int?

 b?.length()

 

 2.3、"?:" -> 如果 "?:" 左边表达式不为空则返回,否则返回右边的表达式。(注意:右边的表带式只有在左边表达式为空是才会执行)

 

val l = b.length()?: -1

 

 2.4、"!!" -> 返回一个非空的 b 值 或者如果 b 为空,就会抛出一个 NPE(空指针) 异常:

val l = b!!.length


 2.5、"=="与"===" -> "=="判断值是否相等,"==="判断值及引用是否完全相等。

val num: Int = 128;
val a:Int? = num
val b:Int? = num
println(a == b)
print(a === b) 

 
3、Kotlin常用操作符  
 3.1、"?:" Elvis操作符
      如果 "?:" 左边表达式非空,elvis操作符就会返回左边的结果,否则返回右边的结果。请注意,仅在左侧为空的时候,右侧的表达式才会计算
    

val a = b?.length?:-1

//等同于:

val a: Int = if(b != null) b.length else -1


 3.2、"as?" 安全转换 
      当使用 as 转型的时候,可能会经常出现 ClassCastException。 所以,现在可以使as?安全转型,当转型不成功的时候,它会返回 null。
 注:在使用intent传值的时候,会出现空字符串不能用as强制转型,这是应该使用as?

 val m: Int? = a as? Int


 3.3、":" 冒号 用于类的继承,变量的定义 
      1、类型和超类型之间的冒号前要有一个空格 
      2、实例和类型之间的冒号前不要空格

 //定义全局变量时
 var str: String? = null

 //类的继承与变量定义
 class TestActivity<T : Serializable>(str: String) : Activity{} 


 3.4、"is" 类型判断符
      检查某个实例是否是某个类型,如果判断出属于某个类型,那么判断后的分支中可以直接可当该类型使用,无需显示转换
    

  fun getStringLength(obj: Any): Int? {
        //obj在&&右边自动动转换成"String"类型
        if (obj is String && obj.length > 0)
            return obj.length
        return null
  }




 3.5、".."、"until" 操作符 以及 "in" 和 "!in" 操作符
      ".." 代表从x到y,包括x和y,这是一个闭区间运算符,而
     "until" 则是半闭区间运算符,代表从a到b范围内所有的值,包括a和不包括b。 
      "in" 代表在一个区间中,"!in" 代表不在一个区间中。

 if (i in 1..10) { // 等价于 1 <= i && i <= 10
     println(i)
 }


 //使用until函数,创建一个不包括其结束元素的区间

 for (i in 1 until 10) {   // i in [1, 10) 排除了 10
      println(i)
 }


 3.5.1、downTo()函数
  

//区间内循环:
for (i in 4 downTo 1){
   print(i) //倒叙遍历
}   
// print “4321”


 3.5.2、step()函数 可以进行任意数量的迭代,而不是每次变化都是1

for (i in 1..4 step 2) print(i) // prints "13"
for (i in 4 downTo 1 step 2) print(i) // prints "42"


 3.6、多行输入符 三个双引号
      三引号的形式用来输入多行文本,也就是说在三引号之间输入的内容将被原样保留,之中的单号和双引号不用转义,其中的不可见字符比如/n和/t都会被保留

val str = """ 
           one
           two
           """
//等价于          
val str = "one\ntwo"       
val str =  "one" +"\n"+"two"


 3.7、"::"符号 得到类的Class对象

 startActivity(Intent(this@KotlinActivity, MainActivity::class.java))


 3.8、"@"符号 
 3.8.1、限定this的类型

      
class User {
      inner class State{
         fun getUser(): User{
             //返回User
             return this@User
         }
         fun getState(): State{
             //返回State
             return this@State
         }
      }
}


 3.8.2、作为标签(见4.6详解)

 3.9、"$"操作符
      字符串可以包含模板表达式,及一小段代码,会求值并把结果包含到字符串中。模板字符串以美元符号$开头,由一个简单的名字构成: 
      

 val value:Int=5;
 val str:String="the value is $value"
 
 println("itemB:$itemB")
 //字符串模板
 var userInfo = "name:${user.name},  age:$age"


 或花括号括起来的任意表达式
 

 val g:Int=2
 val h:Int=3
 val str:String="g+h=${g+h}"


 转义字符串和原生字符串都支持模板字符串。如果想要在原生字符串中使用$(它不支持反斜杠转义),可以使用以下语法:
 

 val str:String="""the price is ${'$'}199"""


 4、条件表达式的使用


 4.1、"if/else" 语句规则:
      ①if后的括号不能省略,括号里表达式的值最终必须返回的是布尔值
      ②如果条件体内只有一条语句需要执行,那么if后面的大括号可以省略,但这是一种极为不好的编程习惯。
      ③对于给定的if,else语句是可选的,else if 语句也是可选的
      ④else和else if同时出现时,else必须出现在else if 之后
      ⑤如果有多条else if语句同时出现,那么如果有一条else if语句的表达式测试成功,那么会忽略掉其他所有else if和else分支。
      ⑥如果出现多个if,只有一个else的情形,else子句归属于最内层的if语句
 
 4.1.1、传统用法

        val a = 10
        val b = 20
        var max_0: Int = a


        if (a > b) {
            max_0 = a
  
        } else {
            max_0 = b
        }


        println("----------------------------------")
        println("max_0:$max_0")
        println("----------------------------------")


        // Log
        --------------
        max_0:20
        --------------
  


 4.1.2、作为表达式


   var max_1 = if (a > b) a else b
   println("--------------")
   println("max_1:$max_1")
   println("--------------")


   //Log
   --------------
   max_1:20
   --------------


 4.1.3、作为代码块


   println("--------------")
   val max_2 = if (a > b) {
       println("Choose a")
       a
   } else {
       println("Choose b")
       b
   }


   println("max_2:$max_2")
   println("--------------")


   // Log  
   --------------
   Choose b
   max_2:20
   --------------


   if 作为代码块时,最后一行必须为该块的返回值.
   如果 if 表达式只有一个分支, 或者分支的结果是 Unit , 它的值就是 Unit 。



 4.2、"when"
  when会对所有的分支进行检查直到有一个条件满足。 when 可以用做表达式或声明。
 如果用作表达式的话,那么满足条件的分支就是总表达式。
 如果用做声明,不满足条件的分支的的的值会被忽略,只保留满足条件的分支,而且返回的值也是最后一个表达式的值。


 4.2.1、传统用法
  

        val x : Int = 10
        when (x) {
            9 -> println("x:${x + 10}")
            10 -> println("x:$x")
            else -> print("x:$x")
        } 
  


 4.2.2、分支条件一致
        如果有分支可以用同样的方式处理的话, 分支条件可以连在一起处理。
 

when (x) {
    0,1 -> print("x == 0 or x == 1")//同样的方式处理
    else -> print("otherwise")
}
  


 4.2.3、使用任意表达式作为分支的条件  
        

when (x) {
    parseInt(s) -> print("s encode x")
    else -> print("s does not encode x")
}


when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid")
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}



 4.2.4、作为表达式
        

val hasPrefix = when (x) {
    is String -> x.startsWith("prefix")
    else -> false
}


 4.3、"for"
      for 循环通过任何提供的迭代器进行迭代。 语法如下:
      

 for (item in collection)
     print(item)
 
 //如果遍历list或者array可以通过索引进行迭代:
      
 for (i in array.indices)
     print(array[i])
 
 


 4.4、"while" 循环
 
 4.4.1、"while"语句:while语句在循环刚开始时,会计算一次布尔表达式的值,如果满足条件,进入循环,
                   如果不满足条件,将跳出循环。而在while语句的下一次迭代开始前会计算再一次布尔值,如此重复。
        

while (x > 0) {
    x--
} 
 


 4.4.2、"dowhile"语句:dowhile语句与while语句类似,唯一的区别是doWhile语句会至少执行一次,即便布尔表达式的第一次计算就是false。而while语句中,如果 布尔表达式的第一次计算的值是false,该循环不会执行。
 
 4.5、返回与跳转 Kotlin中有"return"、"break"、"continue"等三种返回跳转操作符。
 
 4.5.1、"return" ①指定一个方法返回什么值 ②导致当前方法结束,并返回返回指定的值  

   
fun main(args: Array<String>) {
    println("testA:${testA(10)}")
    println("----------")
    println("testB:${testB(10)}")
}


fun testA(a : Int):Int{
    if (a > 0) {
        return -1
    } else {
        return 1
    }
}


fun testB(a : Int):Int{
    println("a:$a")
    if (a > 0) {
        return -1
    } else {
        return 1
    }
    a++
    print("a:$a")
}


// Log打印
testA:-1
----------
a:10
testB:-1
 


 4.5.2、"break" 结束最近的闭合循环,不执行循环中剩余的语句  
 


     val arraysA = listOf("A", "B", "C", "D")
     val arraysB  = listOf(1,2,3,4)
     for (itemA in arraysA) {
         for (itemB in arraysB) {
             if (itemB > 2) {
                 break
             }
             println("itemB:$itemB")
         }


         if (itemA == "C") {
             break
         }
         println("itemA:$itemA")
     }


     // Log
     itemB:1
     itemB:2
     itemA:A
     itemB:1
     itemB:2
     itemA:B
     itemB:1
     itemB:2


   从Log打印可以看出,第一个break结束的是for (itemB in arraysB)这个循环,
而第二个break结束的是for (itemA in arraysA),它们的共通点就是结束都是距离它们最近的一个循环。
 

 4.5.3、"continue" 跳到最近的闭合循环的下一次循环
 
 

  val arraysA = listOf("A", "B", "C", "D")
   val arraysB  = listOf(1,2,3,4)


   for (itemA in arraysA) {
       var i : Int = 0
       for (itemB in arraysB) {
           i++
           if (itemB > 2) {
               continue
           }
           println("itemB:$itemB")
       }


       if (itemA == "C") {
           continue
       }
       println("i:$i")
       println("itemA:$itemA")
       println("---------")
   }


   // Log
   itemB:1
   itemB:2
   i:4
   itemA:A
   ---------
   itemB:1
   itemB:2
   i:4
   itemA:B
   ---------
   itemB:1
   itemB:2
   itemB:1
   itemB:2
   i:4
   itemA:D
   ---------   


   从上述Log上,可以清楚看到,两个循环分别循环了四次,但是在碰到continue时,会跳出当前循环并执行下一次循环。
 
 4.6、标签   在 Kotlin 中表达式可以添加标签,标签通过@结尾来表示,比如:abc@,fooBar@
 

 loop@ for (i in 1..100){
     //...
 }


 
 4.6.1、"break"和标签
 

   val arraysA = listOf("A", "B", "C", "D")
   val arraysB  = listOf(1,2,3,4) 
   loop@ for (itemA in arraysA) {
       var i : Int = 0
       for (itemB in arraysB) {
           i++
           if (itemB > 2) {
               break@loop
           }


           println("itemB:$itemB")
       }


       println("i:$i")
       println("itemA:$itemA")
       println("---------")
   }


   // Log打印
   itemB:1
   itemB:2


从Log打印,第一个循环执行了一次,第二个循环执行了两次,便跳出了封闭的循环。
意味着break跳到标签后边的表达式,并不再执行此表达式直接跳过,执行后边的语句。
 
 4.6.2、"continue"和标签



   val arraysA = listOf("A", "B", "C", "D")
   val arraysB  = listOf(1,2,3,4) 
loop@ for (itemA in arraysA) {
    var i : Int = 0
    for (itemB in arraysB) {
        i++
        if (itemB > 2) {
            continue@loop
        }


        println("itemB:$itemB")
    }


    println("i:$i")
    println("itemA:$itemA")
    println("---------")
}


// Log打印
itemB:1
itemB:2
itemB:1
itemB:2
itemB:1
itemB:2
itemB:1
itemB:2
 


   之前说过,continue是跳到最近的闭合循环的下一次循环,但是加上标签以后,直接跳转到了第一个循环,也就是for (itemA in arraysA),
并没有执行最近的闭合循环的下一次循环。意味着continue直接跳转到标签后面的语句并执行。
 
 4.6.3、"return"和标签  

   
val ints = listOf(0, 1, 2, 3)
fun main(args: Array<String>) {
    foo()
}
fun foo() {
    ints.forEach {
        if (it ==0) return@forEach
        println(it)
    }
}
// Log打印
1
2
3


        
从Log打印可以看出,return会跳转到标签后边的表达式处,并执行该表达式。
 
 4.6.4、命名函数自动定义标签
 


        foo outer() {
            foo inner() {
                return@outer
            }
        } 


 4.6.5、作用域
 

       
        val ints = listOf(0, 1, 2, 3)
        fun main(args: Array<String>) {
            list@
            foo()


        }


        fun foo() {
            ints.forEach {
                if (it ==0) return@forEach
                println(it)
            }
//return @list//这么调用会报错,会提示“Unresolved reference:@list”
        } 


         
        从作用域来看,标签和变量是一致的,都有相对应的作用域。在main方法里面定义了一个标签list@,在foo方法里面调用时,
提示“Unresolved reference:@list”,意味着list标签的作用域应该在main方法里,在foo方法里并不能够调用。 
 
 
感谢

https://github.com/huanglizhuo/kotlin-in-chinese
http://blog.csdn.net/IO_Field/article/details/52842596
http://blog.csdn.net/jhj_24/article/details/53887820 
 
 
 
 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值