Kotlin学习指南——基本语法、基本数据类型、条件及循环控制

1. 基本语法

  1. 包声明, 可以为任意
import java.util.* 包带入,结尾不带;
  1. 基本语法
    fun main(args: Array<String>) {    // 包级可见的函数,接受一个字符串数组作为参数
        println("Hello World!") // 分号可以省略
        for(item : String in args){
            print("main item = $item \n")

        }

        Greeter("World!").greet()
    }
  1. 面向对象编程
 class Greeter(val name: String) {
        fun greet() {
            println("Hello, $name \n")
        }
    }
  1. 函数定义
    4.1 函数定义使用关键字 fun,参数格式为:参数 : 类型
 fun sum(a: Int, b: Int): Int {   // Int 参数,返回值 Int
        return a + b
    }
4.2  表达式作为函数体,返回类型自动推断:
fun sum1(a: Int, b: Int) = a + b

4.3 public 方法则必须明确写出返回类型

public fun sum2(a: Int, b: Int): Int = a + b

4.4 无返回值的函数(类似Java中的void):

fun printSum(a: Int, b: Int): Unit {
        print(a + b)
    }

4.5 如果是返回 Unit类型,则可以省略(对于public方法也是这样):

 public fun printSum1(a: Int, b: Int) {
        print(a + b)
    }

4.6 可变长参数函数
函数的变长参数可以用 vararg 关键字进行标识:

  fun vars(vararg v:Int){
        for(vt in v){
            print(vt)
        }
    }

4.7 lambda(匿名函数)
lambda表达式使用实例:

 fun sumLambdaTest(a: Int, b: Int) {
        val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
        println(sumLambda(a,b))  // 输出 3
    }

    //单例写法
    companion object {
        @Volatile private var INSTANCE: Lesson01_BasicLangGrammar? = null

        fun getInstance(): Lesson01_BasicLangGrammar =
                INSTANCE ?: synchronized(this){
                    INSTANCE
                            ?: Lesson01_BasicLangGrammar().also { INSTANCE = it }
                }
    }
  1. 常量与变量
    可变变量定义:var 关键字

    var <标识符> : <类型> = <初始化值>
    不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)

    val <标识符> : <类型> = <初始化值>
    常量与变量都可以没有初始化值,但是在引用前必须初始化

    编译器支持自动类型判断,即声明时可以不指定类型,由编译器判断。

 fun constAndVar(){
        val a: Int = 1
        val b = 1       // 系统自动推断变量类型为Int
        val c: Int      // 如果不在声明时初始化则必须提供变量类型
        c = 1           // 明确赋值


        var x = 5        // 系统自动推断变量类型为Int
        x += 1           // 变量可修改

        print("[constAndVar]a = $a, b = $b, c= $c, x = $x \n")
    }
  1. 注释
    Kotlin 支持单行和多行注释,实例如下:

    // 这是一个单行注释

    /* 这是一个多行的
    块注释。 */

与 Java 不同, Kotlin 中的块注释允许嵌套。

  1. 字符串模板
    $ 表示一个变量名或者变量值

    $varName 表示变量值

    ${varName.fun()} 表示变量的方法返回值:

fun stringTemplate(){
        var a = 1
        // 模板中的简单名称:
        val s1 = "a is $a"
        print(s1)
        a = 2
        // 模板中的任意表达式:
        val s2 = "${s1.replace("is", "was")}, but now is $a"
        print(s2)
    }
  1. NULL检查机制
    Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做空判断处理

    //类型后面加?表示可为空
    var age: String? = “23”
    //抛出异常
    val ages = age!!.toInt()
    //不做处理返回 null
    val ages1 = age?.toInt()
    //age为空返回-1
    val ages2 = age?.toInt() ?: -1
    当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。
    当 str 中的字符串内容不是一个整数时, 返回 null:

    private fun parseInt(str: String?): Int? {
        // ...
        return str?.toInt()
    }

    fun  testNull(age: String?){
        //抛出空指针异常
        val ages = age!!.toInt()
        //不做处理返回 null
        val ages1 = age?.toInt()
        //age为空返回-1
        val ages2 = age?.toInt() ?: -1

        print("ages = $ages, ages1 = $ages1, ages2 = $ages2 \n")
    }

    fun returnNull(args: Array<String>){
        if (args.size < 2) {
            print("Two integers expected")
            return
        }
        val x = parseInt(args[0])
        val y = parseInt(args[1])
        print("x == $x, y == $y \n")
        // 直接使用 `x * y` 会导致错误, 因为它们可能为 null.
        if (x != null && y != null) {
            // 在进行过 null 值检查之后, x 和 y 的类型会被自动转换为非 null 变量
            print(x * y)
        }
    }
  1. 类型检测及自动类型转换
    我们可以使用 is 运算符检测一个表达式是否某类型的一个实例(类似于Java中的instanceof关键字)。
 fun getStringLength(obj: Any): Int? {
        if (obj is String) {
            // 做过类型判断以后,obj会被系统自动转换为String类型
            return obj.length
        }

        //在这里还有一种方法,与Java中instanceof不同,使用!is
        // if (obj !is String){
        //   // XXX
        // }

        // 这里的obj仍然是Any类型的引用
        return null
    }

    //或者
    fun getStringLength1(obj: Any): Int? {
        if (obj !is String)
            return null
        // 在这个分支中, `obj` 的类型会被自动转换为 `String`
        return obj.length
    }

    //或者
    fun getStringLength2(obj: Any): Int? {
        // 在 `&&` 运算符的右侧, `obj` 的类型会被自动转换为 `String`
        if (obj is String && obj.length > 0)
            return obj.length
        return null
    }
  1. 区间
    区间表达式由具有操作符形式 … 的 rangeTo 函数辅以 in 和 !in 形成。

    区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。以下是使用区间的一些示例:

 fun rangeSample(){
        for (i in 1..4) print(i) // 输出“1234”
        println("\n----------------")
        for (i in 4..1) print(i) // 什么都不输出

        println("\n----------------")

// 使用 step 指定步长
        for (i in 1..4 step 2) print(i) // 输出“13”
        println("\n----------------")
        for (i in 4 downTo 1 step 2) print(i) // 输出“42”
        println("\n----------------")

// 使用 until 函数排除结束元素
        for (i in 1 until 10) {   // i in [1, 10) 排除了 10
            println(i)
            if (i in 1..10) { // 等同于 1 <= i && i <= 10
                println(i)
            }
        }
    }

2. 基本数据类型

2.1 基本类型的变量声明

  1. 数据类型及位宽度及字面常量
    Double 64
    Float 32
    Long 64
    Int 32
    Short 16
    Byte 8
fun constForDataType(){
        val constInt = 123
        val constHex = 0xff
        val constStr = "abc"
        val constLongInt = 123L
        val constBinary = 0b00001011
        //浮点数支持
        val constDouble = 123.5
        val constDouble1 = 123.5e10
        val constFoat = 123.5f
        //你可以使用下划线使数字常量更易读:
        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
    }
  1. 比较两个数
    Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。数字类型也一样,所有在比较两个数字的时候,就有比较数据大小和比较两个对象是否相同的区别了。
    在 Kotlin 中,三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小。
 fun numCompare(){
        val a: Int = 10000
        println(a === a) // true,值相等,对象地址相等

        print("=====================\n")
        //经过了装箱,创建了两个不同的对象
        val boxedA: Int? = a
        val anotherBoxedA: Int? = a

        //虽然经过了装箱,但是值是相等的,都是10000
        println(boxedA === anotherBoxedA) //  false,值相等,对象地址不一样
        print("=====================\n")
        println(boxedA == anotherBoxedA) // true,值相等
        print("=====================\n")
    }

2.2 简单变量之间转换

由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。

这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。

每种数据类型都有下面的这些方法,可以转化为其它的类型:

toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char

 fun typeSwitch(){
        val b: Byte = 1 // OK, 字面值是静态检测的
        //val i: Int = b // 错误
        print("b = $b \n")
        //自动类型转化的,前提是可以根据上下文环境推断出正确的数据类型而且数学操作符会做相应的重载。
        val l = 1L + 3 // Long + Int => Long

        print("l = $l \n")
    }

2.3 位操作

对于Int和Long类型,还有一系列的位操作符可以使用,分别是:
shl(bits) – 左移位 (Java’s <<)
shr(bits) – 右移位 (Java’s >>)
ushr(bits) – 无符号右移位 (Java’s >>>)
and(bits) – 与
or(bits) – 或
xor(bits) – 异或
inv() – 反向

 fun bitsOperate(){
        val shLeft = 1.shl(1)
        print("shLeft = $shLeft \n")
        val shRight = 1.shr(1)
        print("shRight = $shRight \n")
        val shUnRight = 100.ushr(2)
        print("shUnRight = $shUnRight \n")
        val andVal = 10.and(0)
        print("andVal = $andVal \n")
        val orVal = 2.or(1)
        print("orVal = $orVal \n")
        val invVal = 1.inv()
        print("invVal = $invVal \n")

    }

2.4 字符

(1)Kotlin 中的 Char 不能直接和数字操作,Char 必需是单引号 ’ 包含起来的。比如普通字符 ‘0’,‘a’。
(2)特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、’、"、\ 和 $。
编码其他字符要用 Unicode 转义序列语法:’\uFF00’。

fun decimalDigitValue(c: Char): Int {
        /*if (c == 1) { // 错误:类型不兼容
            ……
        }*/
        if (c !in '0'..'9')
            throw IllegalArgumentException("Out of range")
        return c.toInt() - '0'.toInt() // 显式转换为数字
    }

2.5 逻辑运算

布尔操作

布尔用 Boolean 类型表示,它有两个值:true 和 false。

若需要可空引用布尔会被装箱。

内置的布尔运算有:

|| – 短路逻辑或
&& – 短路逻辑与
! - 逻辑非
 fun boolOp(){
        val b1 = true
        val b2 = false
        val b3 = b1 || b2
        val b4 = b3 && b2
        var b5 = !b4
    }

2.6 数组声明及操作

  1. 数组声明及初始化
var int_array:IntArray = inArrayOf(1,2,3)

Kotlin基本数据类型名称及其初始化方法对应关系

Kotlin的基本数组类型数组类型的名称数组类型的初始化方法
整型数组IntArrayintArrayOf
长整型数组LongArraylongArrayOf
浮点数组FloatArraylongArrayOf
双精度数组DoubleArraydoubleArrayOf
布尔数组BooleanArraybooleanArrayOf
字符数组CharArraycharArrayOf

示例代码

var long_array:LongArray = longArrayOf(1, 2, 3)
var float_array:FloatArray = floatArrayOf(1.0f, 2.0f, 3.0f)
var double_array:DoubleArray = doubleArrayOf(1.0, 2.0, 3.0)
var boolean_array:BooleanArray = booleanArrayOf(true, false, true)
var char_array:CharArray = charArrayOf('a', 'b', 'c')

特别的字符串数组声明方式如下

var string_array:Array<String> = arrayOf("How", "Are", "You")

使用Array<数据类型> 方式声明的方式也可以推广到其他数据类型
如下示例代码:

var int_array:Array<Int> = arrayOf(1, 2, 3)
var long_array:Array<Long> = arrayOf(1, 2, 3)
  1. 数组操作
    (1) 获取数组长度使用size熟悉
    (2)获取数组元素,可以使用下标,也可以使用get()set()方法,所以, 我们可以通过下标很方便的获取或者设置数组对应位置的值。
    数组的创建两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数。如下所示,我们分别是两种方式创建了两个数组:
 fun arrayOp(){
        //[1,2,3]
        val a = arrayOf(1, 2, 3)
        //[0,2,4]
        val b = Array(3, { i -> (i * 2) })

        //读取数组内容
        //这里使用下标获取元素,也可以是a.get(0) 方式获取
        println(a[0])    // 输出结果:1
        print("=====================\n")
        println(b[1])    // 输出结果:2
        print("=====================\n")

        val x: IntArray = intArrayOf(1, 2, 3)
        x[0] = x[1] + x[2]
    }

如上所述,[] 运算符代表调用成员函数 get() 和 set()。

注意: 与 Java 不同的是,Kotlin 中数组是不型变的(invariant)。

除了类Array,还有ByteArray, ShortArray, IntArray,用来表示各个类型的数组,省去了装箱操作,因此效率更高,其用法同Array一样,如上例最后一行.

2.7 字符串

  1. 字符串
fun stringSample(){
        //1. 遍历字符串中的字符
        val str = "abcd"
        for (c in str) {
            println(c)
        }
        print("-------------------------------\n")
        //2. 多行字符串
        val text = """
        多行字符串
        多行字符串
        """
        println(text)   // 输出有一些前置空格
        print("-------------------------------\n")
       //3. 通过 trimMargin() 方法来删除多余的空白
        //默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">")
        val text1 = """
        |多行字符串
        |菜鸟教程
        |多行字符串
        |Runoob
        """.trimMargin()
        println(text1)    // 前置空格删除了
    }
  1. 字符串转换
    字符串转其他类型可以使用toInt ,toLong , toFloat 等方法。

  2. 字符串模板
    字符串模板以$开头

 fun stringTemplateSample(){
        val i = 10
        val s = "i = $i" // 求值结果为 "i = 10"
        println(s)
        print("-------------------------------\n")
        //花括号扩起来的任意表达式
        val s1 = "runoob"
        val str = "$s1.length is ${s1.length}" // 求值结果为 "runoob.length is 6"
        print("-------------------------------\n")
        //原生字符串和转义字符串内部都支持模板。 如果你需要在原生字符串中表示字面值 $ 字符(它不支持反斜杠转义)
        val price = """
        ${'$'}9.99
        """
        println(price)
        println(str)
    }
  1. 字符串常用方法

查找子串使用indexOf
截取子串使用substring
替换子串使用replace
分割字符串使用split

示例代码如下

var origin_trim:String = "abbc12.2sds2"
//查找子串
if (origin_trim.indexOf('.') > 0) {
//截取子串
 origin_trim = origin_trim.substring(0, origin_trim.indexOf('.'))
}
//分割字符串
var strList:List<String> = origin.split(".")

3. 条件判定和循环

3.1 条件分支

  1. if语句
 fun ifCondition(a: Int, b:Int){

        // (1).传统用法
        var max = a
        if (a < b) max = b
        print("max = $max \n")
        // (2). 使用 else
        var max1: Int
        if (a > b) {
            max1 = a
        } else {
            max1 = b
        }
        print("max1 = $max1 \n")

        // (3). 作为表达式, 推荐简化写法
        val max2 = if (a > b) a else b

        print("max2 = $max2 \n")

        val max3 = if (a > b) {
            print("Choose a")
            a
        } else {
            print("Choose b")
            b
        }
        print("max3 = $max3 \n")


        //(4). 多分支写法
        var x = 0
        if(x>0){
            println("x 大于 0")
        }else if(x==0){
            println("x 等于 0")
        }else{
            println("x 小于 0")
        }

       //(5). 使用 in 运算符来检测某个数字是否在指定区间内,区间格式为 x..y
        val x1 = 5
        val y1 = 9
        if (x1 in 1..8) {
            println("x 在区间内")
        }
    }
  1. when表达式
    when 将它的参数和所有的分支条件顺序比较,直到某个分支满足条件。

    when 既可以被当做表达式使用也可以被当做语句使用。如果它被当做表达式,符合条件的分支的值就是整个表达式的值,如果当做语句使用, 则忽略个别分支的值。

    when 类似其他语言的 switch 操作符。其最简单的形式如下:

 fun whenCondition(){
        //(1). 一般写法
        val x = 2
        when (x) {
            1 -> print("x == 1 \n")
            2 -> print("x == 2 \n")
            else -> { // 注意这个块
                print("x 不是 1 ,也不是 2 \n")
            }
        }

(2). case合并写法
在 when 中,else 同 switch 的 default。如果其他分支都不满足条件将会求值 else 分支。
如果很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔:

when (x) {
        0, 1 -> print("x == 0 or x == 1 \n")
        else -> print("otherwise \n")
    }

(3). 也可以检测一个值在(in)或者不在(!in)一个区间或者集合中

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

(4). 另一种可能性是检测一个值是(is)或者不是(!is)一个特定类型的值。
注意:由于智能转换,你可以访问该类型的方法和属性而无需 任何额外的检测。

 var hasPref = hasPrefix(x)
print("hasPref = $hasPref \n")

 private fun hasPrefix(x: Any) = when(x) {
        is String -> x.startsWith("prefix")
        else -> false
    }

(5). when 也可以用来取代 if-else if链。
如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支

fun xx{
 val items = setOf("apple", "banana", "kiwi")
        when {
            "orange" in items -> println("juicy \n")
            "apple" in items -> println("apple is fine too \n")
        }

    }

总结:
对于条件分支的处理,Kotlin实现了简单分支和多路分支,简单分支跟Java一样都是if/else语句,多路分支则由Java的switch/case语句升级为when/else语句。同时,Kotlin条件分支允许有返回值,是较大的改进。Java的三元运算符”变量名=条件语句?取值A:取值B “ 在Kotlin中取消了,对应功能改为使用if/else实现; Java的关键字instanceof也取消了,取而代之的是关键字is, 并且多路分支也允许判断变量类型。

3.2 循环控制

  1. 循环控制
    for 循环可以对任何提供迭代器(iterator)的对象进行遍历,语法如下:
 for (item in collection) print(item)
循环体可以是一个代码块:
 for (item: Int in ints) {
        // ……
    }

如上所述,for 可以循环遍历任何提供了迭代器的对象。
如果你想要通过索引遍历一个数组或者一个 list,你可以这么做:

 for (i in array.indices) {
        print(array[i])
    }

注意这种"在区间上遍历"会编译成优化的实现而不会创建额外对象。
或者你可以用库函数 withIndex:

for ((index, value) in array.withIndex()) {
        println("the element at $index is $value")
    }

    fun sampleForLoop(){
        val items = listOf("apple", "banana", "kiwi")
        for (item in items) {
            println(item)
        }

        print("-------------------\n")

        for (index in items.indices) {
            println("item at $index is ${items[index]}")
        }
    }

for的其他用法

//左闭右开区间,合法值包括11,但不包括66
for(i in 11 until 66) {...}
//每次默认递增1,这里改为每次递增4
for(i in 23..89 step4) {...}
//for循环默认递增,这里使用downTo表示递减
for(i in 50 downTo 7) {}
  1. while与do…while循环

    while是最基本的循环,它的结构为:

     while( 布尔表达式 ) {
         //循环内容
     }
    

    do…while 循环 对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。

    do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。

     do {
         //代码语句
     }while(布尔表达式);
    
  fun sampleForWhile(){
        println("----while 使用-----")
        var x = 5
        while (x > 0) {
            println( x--)
        }
        println("----do...while 使用-----")
        var y = 5
        do {
            println(y--)
        } while(y>0)
    }
  1. 返回与跳转

    Kotlin 有三种结构化跳转表达式:

    return。默认从最直接包围它的函数或者匿名函数返回。
    break。终止最直接包围它的循环。
    continue。继续下一次最直接包围它的循环。
    在循环中 Kotlin 支持传统的 break 和 continue 操作符。

   fun returnAndBreak(){
        for (i in 1..10) {
            if (i==3) continue  // i 为 3 时跳过当前循环,继续下一次循环
            println(i)
            if (i>5) break   // i 为 6 时 跳出循环
        }
    }
  1. Break 和 Continue 标签
    在 Kotlin 中任何表达式都可以用标签(label)来标记。 标签的格式为标识符后跟 @ 符号,
    例如:abc@、fooBar@都是有效的标签。 要为一个表达式加标签,我们只要在其前加标签即可。

     loop@ for (i in 1..100) {
         // ……
     }
    
 fun labelSample(){
        //标签限制的 break 跳转到刚好位于该标签指定的循环后面的执行点。
        // continue 继续标签指定的循环的下一次迭代。
        loop@ for (i in 1..25) {
            for (j in 1..21) {
                if (j>20) break@loop
                print("i= $i, j= $j")
                if(j == 10)continue
            }
        }
    }
  1. 标签处返回

    (1) 通常我们return是从包围它的函数返回,如下是直接返回到loop

 fun foo() {
        ints.forEach lit@ {
            if (it == 0) return@lit
            print(it)
        }
    }

(2) 从lambda表达式返回

fun foo() {
        ints.forEach lit@ {
            if (it == 0) return@lit
            print(it)
        }
    }

(3) 现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便。 该标签与接受该 lambda 的函数同名。

fun foo() {
        ints.forEach {
            if (it == 0) return@forEach
            print(it)
        }
    }

(4)或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回.

  fun foo() {
        ints.forEach(fun(value: Int) {
            if (value == 0) return
            print(value)
        })
    }

当要返一个回值的时候,解析器优先选用标签限制的 return,即

return@a 1

意为"从标签 @a 返回 1",而不是"返回一个标签标注的表达式 (@a 1)"。

fun labelReturnSample(){
        val intArray = arrayListOf(1,2,3,0,8)
        intArray.forEach {
            if (it == 0) return@forEach
            print("it = $it \n")
        }

        print("label sample test ")
    }

总结:
对于循环语句的操作,Kotlin仍然保留for和while两种循环,主要区别在于Kotlin取消了”for(初始;条件;增减)“ 这个规则,同时新增了对跳出多重循环的支持(通过"break@标记位"实现。)

3.3 空安全

声明不为空变量和可空变量

//变量不可为空
var strNotNull: String = ""
//变量可为空
var strCanNull:String?

Kotlin检验字符串空值的几个方法

  • isNullOrEmpty :为空指针或者字符串长度为0时返回true, 非空串与可空串均可调用。strNotNull与strCanNull都可调用
  • isNullOrBlank:为空指针、字串长度为0或者全为空格时返回true,非空串与可空串均可调用。strNotNull与strCanNull都可调用
  • isEmpty: 字符串长度为0时返回true, 只有非空串可调用。strNotNull可调用
  • isBlank : 字符串长度为0或者全为空格时返回true,只有非空串可调用。strNotNull可调用
  • isNotEmpty:字串长度大于0时返回true,只有非空串可调用。strNotNull可调用
  • isNotBlank:字串长度大于0且不是全空格串时返回true,只有非空串可调用。strNotNull可调用

判断字符串长度
非空字符串可以直接使用length, 可空字符串需要做空判定

var length = if(strCanNull!=null) strCanNull.length: -1

对于上述判定,可以做如下简化

//?.表示变量为空直接返回null,所以返回值的变量必须被声明为空类型
var length_null = strCanNull?.length
println("使用?.得到字符串长度为$length_null")

length_null仍然可能为null,于是有如下写法

//?:表示为空时就返回右边的值,即(x!=null)?x.**:y
var length = strCanNull?.length?:-1

对于变量值确定不为空时,可以使用非空断言

str = "abcsds"
try {
//断言str为非空, 如果是null则通过try{}catch{}捕获
length = str!!.length
} catch(e: Exception){
//发现nullPointerException
}

3.4 等式判定

3.4.1 结构相等

字符串比较

strA == strB //判断两个字符串是否相等
strA != strB //判定两个字符串是否相等

但凡Java中实现了equals函数的类,其变量均可在Kotlin中通过运算符"==" 和”!=“进行等式判断。这种不比较存储地址,而是比较变量结构内部值的行为,Kotlin称之为结构相等,即模样相等。

3.4.2 引用相等

除了要求结构相等外,还要求地址也相同 ,示例代码如下:

val date1:Date = Date()
val date2:Any = date1.clone() //从date1原样克隆一份到date2
//结果为false, 值相等但是地址不相等
val result = date1 === date2
//结果为true, 值相等但是地址不相等
val result2 = date1!== date2

3.4.3 is和in

  1. 运算符 is 和 !is
    同Java的instanceof 用于验证变量是否属于某种类型
val oneLong:Long = 1L
//判断是否属于Long类型
val result = oneLong is Long
//判定不属于Long类型
val result2 = oneLong !is Long
  1. 运算符in 和 !in
    校验数组中是否存在某个元素。
val oneArray:IntArray = intArrayOf(1, 2, 3, 4, 5)
val four:Int = 4
val nine:Int = 9
val result = four in oneArray
val result2 = nine !in oneArray

3.5 小结

学习了Kotlin的简单分支和多路分支语句
学习了Kotlin的遍历循环和条件循环语句
学习声明了可空变量,并对可空变量进行各种处理操作
学习了Kotlin的结构相等和引用相等判断,以及变量类型判断,数组存在等值元素判断

4. 参考链接

[Kotlin教程]http://www.runoob.com/kotlin/kotlin-tutorial.html
[学习Kotlin]https://www.kotlincn.net/docs/reference/
[Kotlin 官方参考文档 中文版]https://hltj.gitbooks.io/kotlin-reference-chinese/content/
[使用 Kotlin 开发 Android 应用]https://developer.android.google.cn/kotlin/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Calvin880828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值