Kotlin语法糖--基础

作者: 皮球二二 | 来源:发表于2017-08-17 17:31 被阅读110次

    不管你学习什么语言,开篇都是介绍基本类型,然后就是诸如控制流这种入门语法,随后就是对象、函数的使用,最后就是此语言的高级语法了。所以我们也按照这个流程,今天先介绍些简单的知识
    本篇文章涉及到的代码已经提交到Github

    • 基本类型

    其实Kotlin中所有东西都是对象,这跟Java有点区别

    • 数字

    Kotlin对数字的处理在某种程度上接近Java,但是并不完全相同,比如Java可以将int隐式转换为long,这点Kotlin做不到。
    Kotlin提供如下几种类型来表示数字

    Type Bit width
    Double 64
    Float 32
    Long 64
    Int 32
    Short 16
    Byte 8
    • 数值常量字面值

    Kotlin支持二进制、十进制、十六进制,不支持八进制。这里还有几点要注意下:
    (1) Long类型要在最后加“L”进行标记,比如100L
    (2) 有浮点数默认都为Double,如果你想用Float来表示,那么就要在最后加“F”进行标记,例如100f

    • 数值常量字面值中的下划线

    这个一般体现在可读性上,比如你说说看100000是多少?在Java中你要从个十百千万的一个个点才知道,但是Kotlin就不同了,看代码

    val a: Int=10000
    val b: Int=10_000
    println(a== b)  // 返回true
    
    • 装箱与拆箱

    刚说了Kotlin中所有东西都是对象,而Java则是将数字存储为JVM的原生类型。所以Kotlin装箱之后,同一性不会被保留,但是保留了相等性。来看看代码吧

    val boxA: Int? = a
    var anotherBoxA: Int? = a
    println(boxA == anotherBoxA)
    println(boxA === anotherBoxA)
    
    运行结果
    • 显式转换

    Kotlin里较小类型数不是较大类型数的子类型,所以不能直接隐式转换,并且代码也编译不过去

    val a: Int=10000
    val c: Long = a  // 无法编译通过
    

    我们可以通过显式的来进行转换

    val c: Long = a.toLong()
    

    每个数字类型支持如下的转换:
    (1) toByte()
    (2) toShort()
    (3) toInt()
    (4) toLong()
    (5) toFloat()
    (6) toDouble()
    (7) toChar()

    • 字符

    字符要用Char类型表示,不能直接当数字使用。字符字面值用单引号括起来,比如'a'。特殊字符可以用反斜杠转义,支持如下几个转义序列\t、\b、\n、\r、\'、 \"、\\和$,其他编码类型要使用Unicode转义序列语法,比如'\uFF00'

    • 布尔

    两个值true和false

    • 数组

    数组在Kotlin中使用Array类来表示
    我们一般使用arrayOf来创建一个数组并将元素传递给它

    var array: Array<String> = arrayOf("1", "2", "3")
    

    或者通过arrayOfNulls创建一个指定数量并且元素都为空的数组

    var array1 = arrayOfNulls<String>(5)
    

    甚至我们可以通过Array的构造方法创建一个基于索引来确定每个元素值的数组

    var array2 = Array(5) {
        "$it+Demo"
    }
    

    此处涉及到高阶函数部分,我们在后面会详细说明
    数组可以通过[]运算符来调用成员函数get与set

    var array: Array<String> = arrayOf("1", "2", "3")
    array[0]
    println(array[0])
    array[1]="4"
    println(array[1])
    

    还有ByteArray、ShortArray、IntArray,这些跟Array并没有继承关系,但是它们都有同样的方法属性集

    • 字符串

    • 字符串字面值

    Kotlin中的字符串分为转义字符串以及原生字符串。
    转义字符串跟Java的差不多,来看看

    val text1="Hello \n"
    

    原生字符串使用三个引号(""")分解符括起来,内部没有转义并且可以包含换行和任何其他字符

    var text= """
        |ABC""
        |DEF
        |GHI
        """
    println(text.trimMargin())
    
    运行结果

    默认是使用"|"作为边界前缀,你也可以选择其他字符作为参数传入

    • 字符串模板

    字符串可以包含模板表达式,即一些小段代码,并求值把结果合并到字符串中。模板表达式以美元符号$开头

    var text="World"
    val text12="Hello $text"
    
    运行结果

    除此之外,他还可以将表达式通过花括号括起来进行结果显示

    println("1+2=${1+2}")
    
    运行结果

    最后一点,原生字符串中如果想实现转义功能,也可以通过字符串模板去实现

    var text= """
        |ABC""
        |1+2=${'\n'}
        |DEF
        |GHI
        """
    println(text.trimMargin())
    
    运行结果

    Kotlin中这部分跟Java还是差不多的
    我现在同时定义2个类


    目录结构

    ClassA与ClassB基本上都是相同的,他们都有一个相同的类名字,叫APP


    名字相同的类
    好了我们现在要同时使用这2个类了
    val appa: APP = APP()
    val appb: APP = APP()
    

    这样肯定不行的,这个谁不知道啊
    要是在Java里面,肯定有一个类的变量类型是全路径显示的,就像这样

    APP app=new APP();
    com.renyu.kotlin.chapter2.b.APP app1=new com.renyu.kotlin.chapter2.b.APP();
    

    这个实在是太长了是不是。Kotlin就有一个舒服的解决办法,用as关键字来重命名相同命名的冲突项

    import com.renyu.kotlin.chapter2.b.APP as BAPP
    import com.renyu.kotlin.chapter2.a.APP
    

    这样呢,b包中的APP类就可以通过BAPP来声明了

    val appa: APP = APP()
    println(appa.value)
    val appb: BAPP = BAPP()
    println(appb.value)
    
    • 控制流

    • if表达式

    这个在之前的文章中已经提及了很多,这里也是说重点。除了可以像Java一样作为语句来使用之外,如果你将其作为表达式来使用,必须要有else分支

    var a1=10
    var b2=20
    var maxValue: Int = if (a1>b2) {
        println(a1)
        a1
    } else {
        println(b2)
        b2
    }
    println(maxValue)
    

    最后的表达式就是该语句的值

    • when表达式

    when取代了switch语句,但是它并不仅仅是替代作用,在使用上when表达式还进行了扩展升级。常用的形式有三种:常量结构、in结构、表达式结构。
    when语句与switch语句的区别是,如果符合判断中的任意一条表达式,则在执行表达式对应的语句体之后,直接跳出整个when逻辑,我们不需要手动的break。
    如果when语句作为一个表达式来使用,必须要有else分支,除非编译器检测出来你把所有可能发生的情况都考虑到了
    先看下典型使用

    fun getValue(value: Int) : String {
        return when(value) {
            1 -> "a"
            2 -> "b"
            else -> "other"
        }
    }
    

    如果我们希望一个逻辑值value能够对应多个常量值,则我们就必须使用in结构。其操作,与常量结构的when语句类似,即将满足一个条件的多个常量值使用 “,” 隔开如果想合并多个分支,那么用逗号分隔即可

    fun getValue(value: Int) : String {
        return when(value) {
            1,3 -> "a"
            2 -> "b"
            else -> "other"
        }
    }
    

    同样可以使用任意表达式作为分支条件

    fun getValue(value: Int) : String {
        return when(value) {
            1,3 -> "a"
            2 -> "b"
            "5".toInt() -> "e"
            else -> "other"
        }
    }
    

    当然,我们也可以将多个表达式对应一个判断同时使用,只需要在两个表达式之间增加“,”符号

    最后,我们可以用when来取代if-else if链,我们来改写一下上文的if表达式的例子

    var maxValue1: Int = when {
        (a1>b2) -> {
            a1
        } else -> {
            b2
        }
    }
    println(maxValue1)
    
    • for循环

    不多说了

    • while循环

    不多说了

    • 返回和跳转

    跟Java一样,也是break、continue、return,对比一下Java的写法,应该就能清楚明白了

    • break,continue标签
    String[] arrays={"1", "2", "3", "4", "5"};
    outer:
    for (String array : arrays) {
        System.out.println("1. "+array);
        for (int i=0;i<3;i++) {
            System.out.println("1. "+i);
            if (i==2) {
                break outer;
            }
        }
    }
    
    var array3: Array<String> = arrayOf("1", "2", "3", "4", "5")
    loop@ for (s in array3) {
        println("1. $s")
        for (i in  0..3) {
            println("2. $i")
            if (i==2) {
                break@loop
            }
        }
    }
    

    这里我们可以通过标签来控制返回和跳转流程,标签的格式为标识符后跟@符号

    • 标签处返回

    来看一下这几行代码

    fun foo() {
        var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
        array.forEach {
            if (it == "2") {
                return
            }
            println("$it")
        }
        println("结束")
    }
    

    一旦执行到了这个return,那么我们就将从foo中返回了。我现在想仅从forEach中跳出当前循环,那就必须要给他加标签来限制return了

    fun foo() {
        var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
        array.forEach a@{
            if (it == "2") {
                return@a
            }
            println("$it")
        }
        println("结束")
    }
    
    return@标签跳出当前Lambda表达式

    通常情况下隐式标签更为方便,该标签与lambda的函数同名,即

    fun foo() {
        var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
        array.forEach {
            if (it == "2") {
                return@forEach
            }
            println("$it")
        }
        println("结束")
    }
    

    入门语法就讲到这里了,下回我们来说说类和对象

    相关文章

      网友评论

        本文标题:Kotlin语法糖--基础

        本文链接:https://www.haomeiwen.com/subject/zqggrxtx.html