美文网首页
Kotlin In Action学习笔记1

Kotlin In Action学习笔记1

作者: 蒋扬海 | 来源:发表于2017-06-20 17:29 被阅读0次

    先来说说一些Kotlin的基本特点

    • Kotlin和Java一样是一门静态语言,这意味着所有表达式的类型在编译期已经确定了。
    • Kotlin的运行时库体积非常小,所以不会导致你使用了Kotlin以后程序体积增大很多
    • Kotlin程序的代码简洁,这是Kotlin最让人印象深刻的地方,这得益于Kotlin简洁的语法和函数式编程在Kotlin中的广泛使用。当然语法更简洁,必然就需要编译器做更多的事情,所以Kotlin完全重新编译一个工程的速度是比Java要慢点,不过在增加编译点时候却能够提供更快的编译性能。
    • Kotlin另一个亮点是空安全。我们不必再为冷不丁冒出来的空指针异常而烦恼,因为Kotlin默认是空安全的,他会在编译阶段就检查潜在的空指针异常并提示你,而不是在运行期以让程序崩溃的方式来警告你。
    • 和Java良好的互操作性。Kotlin一开始就瞄准了与现有的Java项目的集成问题,所以官方说他们能完美的与Java实现相互操作。

    对于这点,我个人还是有一些疑虑的,毕竟Kotlin语言中有不少的特性在Java中是没有的,虽然的确能够做到相互操作,不过需要开发人员在遇到这些特性的时候做一些特殊的处理,否则会发生一些与预期不符的行为。这些以后我们谈到相关特性的时候再来讨论。

    既然是学习笔记,接下来还是来点实际的吧,我们来看看Kotlin基本语法中的一些特别的点。

    1. 有且只有表达式体函数的返回类型可以省略:
      比如,
        fun max(a: Int, b: Int): Int = if (a > b) a else b
    

    我们可以写成

        fun max(a: Int, b: Int) = if (a > b) a else b
    
    1. 在Koltin中你可以像脚本语言中一样,在双引号字符串里引用其他变量
       var name = "Leonard Messi"
       println("Hello, $name!")
    

    你还可以这样写

        println("Hello, ${args[0]}!")  // args是一个数组
    

    甚至还可以这样写

        println("Hello, ${if (args.size > 0) args[0] else "someone"}!")
    
    1. 在Kotlin中,if是表达式,而不是语句,它和 Java 中的三元运算符相似:(a > b) ? a : b,所以我们就有这样的代码
    var name = if (a > b) a else b
    
    1. 如果你想定义全局静态常量,那你需要用到const关键字
    const val UNIX_LINE_SEPARATOR = "\n"
    

    它等价于

    public static final String  UNIX_LINE_SEPARATOR = "\n";
    
    1. Kotlin中的可变参数于Java类似,但语法略有不同,我们不使用三个点,而是vararg关键字
    fun listOf<T>(vararg values: T): List<T> { ... }
    val list = listOf(2, 3, 5, 7, 11)
    
    1. 展开操作符,是不是很方便?
    fun main(args: Array<String>) {
           val list = listOf("args: ", *args) //展开运算符展开数组内容
           println(list)
    }
    
    1. 解构声明,同时定义多个变量
    val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")  // define a map
    val (number, name) = 1 to "one"
    

    或者

    for ((index, element) in collection.withIndex()) {
            println("$index: $element")
    }
    
    1. 局部方法,可以让代码更整洁

    2. 安全调用运算符:当你使用可空类型变量又不想空指针异常将整个程序搞崩溃时使用

        fun printAllCaps(s: String?) {
            // allCaps 可能是 null
            val allCaps: String? = s?.toUpperCase()
            println(allCaps)
        }
       
        >> printAllCaps(null)
        null
    
    1. Elvis运算符 ?:,它通常与安全调用运算符结合使用
    fun strLenSafe(s: String?): Int = s?.length ?: 0
    

    如果s?.length为null,那么函数的返回值是0。通常我们在第二个表达式的地方处理异常情况,比如throw一个异常,返回并退出函数等。

    1. 安全转换符as? : as?运算符尝试把值转换成指定的类型,如果值不是合适的类型就返回null
    val otherPerson = o as? Person ?: return false // 这里也结合了Elvis运算符一起使用
    
    1. 非空断言符 !!,类似Java中 调用Assert语句
    fun ignoreNulls(s: String?) {
           // 如果发现s真的为空,会抛出空指针异常
           val sNotNull: String = s!! 
           println(sNotNull.length)
    }
    

    因为Kotlin是空安全的,空指针并不出导致程序异常退出,非空断言在你需要显示的抛出异常时派上用场。(我记得某位同事在当初看到空安全概念时,提到过这个问题)

    1. let函数,可以被任何对象调用,但只有当调用对象非空时,才会执行后续的表达式操作,并且可以将调用对象作为表达式的参数使用;如果调用对象为空,将什么都不做
    email?.let { email -> sendEmailTo(email) }
    
    1. 延迟属性的初始化,我们使用lateinit关键字
    private lateinit var myService: MyService
    

    这样,属性myService的初始化就需要一定要在构造函数中去完成了。但要注意延迟初始化的属性都是var,因为你需要在构造方法外修改它的值。

    1. 可空类型的扩展函数
      在 Java 中,this永远是非空的,因为它引用的是当前你所在这个类的实例。而 在 Kotlin 中,这并不永远成立:在可空类型的扩展函数里,this可以为null。

    2. 数据类型的一些特点

    • Kotlin 中所有基本数据类型都是引用对象,而any是所有对象的跟,类似Object
    • Kotlin 新增了一种Unit类型,类似void,但Unit可以作为类型参数
    • Nothing 类型,没有任何值,在异常处理中有用
    1. 数组: Koltin中用一个类 Array<>来表示
    Array<String>(26) { i -> ('a' + i).toString() }
    

    Kotlin标准库提供给了很多方便函数,toTypedArrayforEachIndexed

    1. 集合(关于集合,内容不少,详情请参考《Kotlin In Action》)
    • Kotlin 提供的大量的集合操作函数,使用非常方便,比如filter,map,sort,sum,filterNotNull等
    • Kotlin 使用Java提供的集合为基础,增加了序列(sequence,用于实现惰性操作)
    • 每一个Java集合在Kotlin中都有两个版本,一个只读,一个可修改

    总结:
    以上是对《Kotlin In Action》第一部分的内容当中的一些要点做了一个梳理,仅供参考。由于篇幅有限,不可能对每个点进行非常详细的阐述,如果想要了解更多的细节,请阅读原书。作者参与翻译的中文版《Kotlin实战》已经翻译完毕,已经在2017年8月正式上市,这是国内第一本权威且全面深入的kotlin教程,值得你拥有!

    相关文章

      网友评论

          本文标题:Kotlin In Action学习笔记1

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