Kotlin简介

欢迎来到 Kotlin 的神秘世界,Kotlin? 嗯,没错就是它! 也许你仅仅是听过它还没开始尝试; 也许你尝试过它但是放弃了; 也许你正在使用它遇到了一些些问题,也许你很喜欢它并且把它使用得如火纯青了。不管你现在是处于哪个阶段,我都希望你能从本教程中得到一些有用的东西。

本教程不打算按照书本上那样平铺直序阐述,而是带着问题和目的性展开,每个语法点主要都围绕着为什么使用它、它是什么、它是如何使用的、它的应用场景此外最后还会带你了解它语法糖背后的原理。因为 Kotlin 是一个门非常讲究实用主义的编程语言,所以一定是要用于解决实际的场景问题,或者相比现有的语言(比如 Java)它如何更高效解决实际问题。每节教程都会留有一个对应的语法练习,下一节会公布上一节的答案。

最后,欢迎一起努力来到 Kotlin 世界探险,一起领悟这门语言背后的设计哲学和实用价值。

1. Kotlin 是什么?

Kotlin 是一门用于现代多平台应用的静态编程语言,其中被广泛用于 Android 平台的开发,被称之为Android 世界的 Swift。它由大名鼎鼎的 JetBrains 公司设计开发并开源,著名的 IDE 工具 IntelliJ IDEA 就是他们的产品,所以无疑他们是对编程语言设计领域最为熟悉的专家。

Kotlin 从 2016 年发布 1.0 的 release 版本开始至今,使用的开发者数量快速增长。

图片描述

此外 Kotlin 已经拥有强大的生态和社区开发者的支持:

  • Kotlin 是著名的 IDE 厂商 JetBrains 公司开发的编程语言
  • 在 Google I/O 2017中,Google 宣布在 Android 上为 Kotlin 提供最佳支持
  • Kotlin 在 Spring5.0 后端开发框架中的支持
  • Kotlin DSL 1.0 将在 Gradle5.0 得以应用,Kotlin 成为继 Groovy 语言开发 Gradle 另一门编程语言
  • Kotlin 成为 2018 年 Github 中增长速度最快的语言
  • 2018年10月,Google 和 JetBrains 在 KotlinConf18 上公开宣布了 Kotlin 基金会
  • 2019年5月,谷歌宣布 Kotlin 作为 Android 的首选语言。
  • 2019年7月,Kotlin 在 O’Reilly 开源软件大会(OSCON)2019上赢得了享有声望的年度突破项目奖

2. 为什么选择 Kotlin?

2.1 简洁

可以大大减少样板代码。

  • 例如实现一个简单的Student 的 POJO 类:
//在Java实现一个Student POJO类,需要写setter,getter模板代码
class Student {
    private String name;
    private int age;
    private String address;
    private String phoneNumber;

    public Student(String name, int age, String address, String phoneNumber) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.phoneNumber = phoneNumber;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}
//Kotlin实现一个Student POJO类,仅仅需要1行代码,就能创建一个包含setter,getter,equals,toString等POJO类
data class(val name: String, val age: Int, val address: String, val phoneNumber: String)
  • 例如实现一个简单的单例模式:
//Java实现一个单例模式
public class Singleton implements Serializable {
    private Singleton() {
    }

    private static final Singleton mInstance = new Singleton();

    public static Singleton getInstance() {//提供公有获取单例对象的函数
        return mInstance;
    }

    public final void doSomething() {
      System.out.println("do some thing");
    }
}
//Kotlin实现上面Java一样的一个单例模式,仅仅只需要创建object即可
object Singleton : Serializable {//object对象表达式天生的单例模式
    fun doSomething() {
        println("do some thing")
    }
}
  • 例如Kotlin中的 kotlin-android-extension助力 Android 开发,从此告别findViewById()模板代码:
//Java实现
public class MainActivity extends Activity {
    private TextView mTvName;
    private TextView mTvAddress;
    private TextView mTvDes;
    private ImageView mIvCover;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvName = (TextView) findViewById(R.id.tv_name);
        mTvAddress = (TextView) findViewById(R.id.tv_address);
        mTvDes = (TextView) findViewById(R.id.tv_des);
        mIvCover = (ImageView) findViewById(R.id.iv_cover);

        mTvName.setText("Kotlin");
        mTvAddress.setText("圣彼得堡附近的科特林岛");
        mTvDes.setText("Kotlin 是一门用于现代多平台应用的静态编程语言");
        mIvCover.setImageDrawable(R.drawable.icon_kotlin_cover);
    }    
}
//kotlin利用kotlin-android-extension实现
class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //无需findViewById直接使用
        tv_name.setText("Kotlin")
        tv_address.setText("圣彼得堡附近的科特林岛")
        tv_des.setText("Kotlin 是一门用于现代多平台应用的静态编程语言")
        iv_cover.setImageDrawable(R.drawable.icon_kotlin_cover)
    }
}

2.2 安全

可以能够很好地避免空指针(NPE)异常的出现。

大家都知道NPE异常是运行时异常,编译期很难发现NPE异常,Kotlin之所以能够很好避免NPE,主要关键在于它对类型系统做了非空和可空类型的划分,并且能在编译期将可能出现NPE的问题提前暴露出来。

  • 声明处赋值处进行 NPE 保护:
//声明处赋值处进行NPE保护
var name: String //定义一个非空String类型
name = null//当非空类型遇到null赋值,则会出现编译错误

var age: Int?//定义一个可空Int类型
age = null //只有当可空类型遇到null赋值,才会编译正常
  • 可以保护避免对可空类型的误操作:
//可以保护避免对可空类型的误操作
val address: String? = null //可空类型
println(address.length());//直接对可空类型操作,会编译错误,此时IDE会提示你这是可空类型变量,不能直接操作,你可能需要判断NPE的问题
  • 更安全的类型检测和类型转化:
//更安全的类型检测和类型转化
fun getStringLength(obj: Any): Int? {
    if (obj !is String)
       return null
    //在这个分支中, obj的类型会被自动转换为String
    return obj.length
}

2.3 互操作性

可以充分利用 JVM、Android 和浏览器的现有库。

  • 可以和 JVM 上的任何现有库有 100% 的兼容性:
//使用RxJava库
fetchUrlList()
          .flatMap {
              return@flatMap Observable.from(it)
          }
          .filter {
              return@filter it.startWith("https")
          }
          .onErrorResumeNext {
              return@onErrorResumeNext Observable.just("https://kotlinlang.org/")            
          }
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(object : Observer<String> {
               override fun onCompleted() {
                  //handle on onCompleted
               }

               override fun onError(e: Throwable) {
                  //handle on onError
               }

               override fun onNext(url: String) {
                  //handle on onNext
               }
          })
  • 可以和现有的 Android 库有很好的兼容性:
import android.graphics.Typeface
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.SpannedString
import android.text.style.StyleSpan
import android.text.style.UnderlineSpan
//Android API中的Spannable库的扩展函数
inline fun buildSpannedString(builderAction: SpannableStringBuilder.() -> Unit): SpannedString {
    val builder = SpannableStringBuilder()
    builder.builderAction()
    return SpannedString(builder)
}

//实现混合Span样式-扩展函数inSpans
inline fun SpannableStringBuilder.inSpans(
        vararg spans: Any,
        builderAction: SpannableStringBuilder.() -> Unit
): SpannableStringBuilder {
    val start = length
    builderAction()
    for (span in spans) setSpan(span, start, length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    return this
}

//实现加粗Span样式-扩展函数bold
inline fun SpannableStringBuilder.bold(builderAction: SpannableStringBuilder.() -> Unit) =
        inSpans(StyleSpan(Typeface.BOLD), builderAction = builderAction)

//实现斜体Span样式-扩展函数italic
inline fun SpannableStringBuilder.italic(builderAction: SpannableStringBuilder.() -> Unit) =
        inSpans(StyleSpan(Typeface.ITALIC), builderAction = builderAction)

//实现下划线Span样式-扩展函数underline
inline fun SpannableStringBuilder.underline(builderAction: SpannableStringBuilder.() -> Unit) =
        inSpans(UnderlineSpan(), builderAction = builderAction)

//调用处
tv_des = buildSpannedString {
      bold {
          append("Kotlin")
      }
      append("是一门用于")
      italic {
          append("现代多平台应用")
      }
      underline {
          append("静态编程语言")
      }
}
  • 可以和JavaScript 平台有很好的兼容性,都可用 Kotlin 写代码然后部署到你想要的地方:
import kotlin.browser.window

fun onLoad() {
    window.document.body!!.innerHTML += "<br/>Hello, Kotlin!"
}

2.4 工具友好

可以用任何 Java IDE 或者使用命令行构建。

图片描述

3. Kotlin能做什么?

如果对 Kotlin 的能力仅仅停留在 JVM平 台,那是片面的。如今的 Kotlin 已经从当初的更好 Java 目标完成了它华丽的大变身,他们的目标已经瞄准了星辰大海。目前 Kotlin 可以适用于移动端跨平台、原生 JVM、服务端开发、Web 开发、Android 开发、数据科学等多个领域。此外近年来 Kotlin 团队已经将重心转移到了语言层面的跨平台,多平台的支持。

图片描述

另一方面,Kotlin 得益于 Kotlin/JVM、Kotlin/JS、Kotlin/Native 三个语言编译器的后端实现,它不仅仅可以编译成 Java 字节码(Kotlin/JVM),也可以编译成JavaScript(Kotlin/JS),还能编译成直接运行在不需要任何VM平台的机器代码(Kotlin/Native),可以轻松实现语言层面的跨平台,并实现在多个平台之间共享代码。目前已经部分支持了Linux、Windows、macOS、WebAssembly、Android、iOS以及watchOS和tvOS平台

图片描述

4. 本教程能学到哪些 Kotlin 技能 ?

  • Kotlin的基本语法和代码规范 ;

  • Kotlin的面向对象;

  • Kotlin的函数式编程;

  • 扩展函数 ;

  • 属性代理 ;

  • 空指针类型安全 ;

  • 运算符重载 ;

  • lambda表达式和高阶函数;

  • 类型系统;

  • 泛型和型变 ;

  • 注解和反射 ;

  • 协程的基本使用;

  • Kotlin 的 DSL;

  • Kotlin 高效实现常用的设计模式;

  • Kotlin 在 Android、IntelliJ IDEA 插件、Gradle、服务端、Web、iOS 等实际应用开发。

5. 本教程适合哪些人群?

  • 零基础的开发者(会从编程语言的最基础开始讲起);

  • 有一定 Java、C 或 C++ 开发基础开发者想学习 Kotlin 开发;

  • Android 开发者想学习 Kotlin 开发 Android 应用;

  • Java 后端开发者想学习 Kotlin 开发后端应用;

  • 对 Kotlin 语言感兴趣的所有开发者。

6. 总结几条学习 Kotlin 的建议?

  • 如果有 Java 编程基础,记住千万不要用 Java 编程思维来写 Kotlin 代码,换句话说不要硬生生把 Java 代码转化成 Kotlin 代码来写,更需要换个思维想如果用 Kotlin 某个语法糖实现的话更优呢,否则将无法真正体会Kotlin这门语言精髓;

  • 记住要善于使用 Kotlin 中的反编译代码插件,就是将 Kotlin 代码反编译成 Java 代码。这是一条非常重要和实用的建议,通过它将会真正看透 Kotlin 语法糖背后原理,从而更高效地使用它;

  • 学会经常去看 Kotlin 源码实现,其实 Kotlin 源码很短的,当知道如何使用某个语法,更需要知道它背后原理以及善于总结它适用的场景;

  • 最后就是多多实践,最好是自己弄个实际的项目,从0到1全部使用 Kotlin 开发,每天一点一点给它舔砖加瓦,通过它来学习每一个 Kotlin 语法技能点。

7. 关于 Kotlin 的一些干货资料