Kotlin簡介
歡迎來到 Kotlin 的神秘世界,Kotlin? 嗯,沒錯就是它! 也許你僅僅是聽過它還沒開始嘗試; 也許你嘗試過它但是放棄了; 也許你正在使用它遇到了一些些問題,也許你很喜歡它并且把它使用得如火純青了。不管你現(xiàn)在是處于哪個階段,我都希望你能從本教程中得到一些有用的東西。
本教程不打算按照書本上那樣平鋪直序闡述,而是帶著問題和目的性展開,每個語法點主要都圍繞著為什么使用它、它是什么、它是如何使用的、它的應用場景此外最后還會帶你了解它語法糖背后的原理。因為 Kotlin 是一個門非常講究實用主義的編程語言,所以一定是要用于解決實際的場景問題,或者相比現(xiàn)有的語言(比如 Java)它如何更高效解決實際問題。每節(jié)教程都會留有一個對應的語法練習,下一節(jié)會公布上一節(jié)的答案。
最后,歡迎一起努力來到 Kotlin 世界探險,一起領悟這門語言背后的設計哲學和實用價值。
1. Kotlin 是什么?
Kotlin 是一門用于現(xiàn)代多平臺應用的靜態(tài)編程語言,其中被廣泛用于 Android 平臺的開發(fā),被稱之為Android 世界的 Swift。它由大名鼎鼎的 JetBrains 公司設計開發(fā)并開源,著名的 IDE 工具 IntelliJ IDEA 就是他們的產(chǎn)品,所以無疑他們是對編程語言設計領域最為熟悉的專家。
Kotlin 從 2016 年發(fā)布 1.0 的 release 版本開始至今,使用的開發(fā)者數(shù)量快速增長。
此外 Kotlin 已經(jīng)擁有強大的生態(tài)和社區(qū)開發(fā)者的支持:
- Kotlin 是著名的 IDE 廠商 JetBrains 公司開發(fā)的編程語言;
- 在 Google I/O 2017中,Google 宣布在 Android 上為 Kotlin 提供最佳支持;
- Kotlin 在 Spring5.0 后端開發(fā)框架中的支持;
- Kotlin DSL 1.0 將在 Gradle5.0 得以應用,Kotlin 成為繼 Groovy 語言開發(fā) 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 簡潔
可以大大減少樣板代碼。
- 例如實現(xiàn)一個簡單的
Student
的 POJO 類:
//在Java實現(xiàn)一個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實現(xiàn)一個Student POJO類,僅僅需要1行代碼,就能創(chuàng)建一個包含setter,getter,equals,toString等POJO類
data class(val name: String, val age: Int, val address: String, val phoneNumber: String)
- 例如實現(xiàn)一個簡單的單例模式:
//Java實現(xiàn)一個單例模式
public class Singleton implements Serializable {
private Singleton() {
}
private static final Singleton mInstance = new Singleton();
public static Singleton getInstance() {//提供公有獲取單例對象的函數(shù)
return mInstance;
}
public final void doSomething() {
System.out.println("do some thing");
}
}
//Kotlin實現(xiàn)上面Java一樣的一個單例模式,僅僅只需要創(chuàng)建object即可
object Singleton : Serializable {//object對象表達式天生的單例模式
fun doSomething() {
println("do some thing")
}
}
- 例如Kotlin中的
kotlin-android-extension
助力 Android 開發(fā),從此告別findViewById()
模板代碼:
//Java實現(xiàn)
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 是一門用于現(xiàn)代多平臺應用的靜態(tài)編程語言");
mIvCover.setImageDrawable(R.drawable.icon_kotlin_cover);
}
}
//kotlin利用kotlin-android-extension實現(xiàn)
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 是一門用于現(xiàn)代多平臺應用的靜態(tài)編程語言")
iv_cover.setImageDrawable(R.drawable.icon_kotlin_cover)
}
}
2.2 安全
可以能夠很好地避免空指針(NPE)異常的出現(xiàn)。
大家都知道NPE異常是運行時異常,編譯期很難發(fā)現(xiàn)NPE異常,Kotlin之所以能夠很好避免NPE,主要關鍵在于它對類型系統(tǒng)做了非空和可空類型的劃分,并且能在編譯期將可能出現(xiàn)NPE的問題提前暴露出來。
- 聲明處賦值處進行 NPE 保護:
//聲明處賦值處進行NPE保護
var name: String //定義一個非空String類型
name = null//當非空類型遇到null賦值,則會出現(xiàn)編譯錯誤
var age: Int?//定義一個可空Int類型
age = null //只有當可空類型遇到null賦值,才會編譯正常
- 可以保護避免對可空類型的誤操作:
//可以保護避免對可空類型的誤操作
val address: String? = null //可空類型
println(address.length());//直接對可空類型操作,會編譯錯誤,此時IDE會提示你這是可空類型變量,不能直接操作,你可能需要判斷NPE的問題
- 更安全的類型檢測和類型轉(zhuǎn)化:
//更安全的類型檢測和類型轉(zhuǎn)化
fun getStringLength(obj: Any): Int? {
if (obj !is String)
return null
//在這個分支中, obj的類型會被自動轉(zhuǎn)換為String
return obj.length
}
2.3 互操作性
可以充分利用 JVM、Android 和瀏覽器的現(xiàn)有庫。
- 可以和 JVM 上的任何現(xiàn)有庫有 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
}
})
- 可以和現(xiàn)有的 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庫的擴展函數(shù)
inline fun buildSpannedString(builderAction: SpannableStringBuilder.() -> Unit): SpannedString {
val builder = SpannableStringBuilder()
builder.builderAction()
return SpannedString(builder)
}
//實現(xiàn)混合Span樣式-擴展函數(shù)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
}
//實現(xiàn)加粗Span樣式-擴展函數(shù)bold
inline fun SpannableStringBuilder.bold(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(StyleSpan(Typeface.BOLD), builderAction = builderAction)
//實現(xiàn)斜體Span樣式-擴展函數(shù)italic
inline fun SpannableStringBuilder.italic(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(StyleSpan(Typeface.ITALIC), builderAction = builderAction)
//實現(xiàn)下劃線Span樣式-擴展函數(shù)underline
inline fun SpannableStringBuilder.underline(builderAction: SpannableStringBuilder.() -> Unit) =
inSpans(UnderlineSpan(), builderAction = builderAction)
//調(diào)用處
tv_des = buildSpannedString {
bold {
append("Kotlin")
}
append("是一門用于")
italic {
append("現(xiàn)代多平臺應用")
}
underline {
append("靜態(tài)編程語言")
}
}
- 可以和JavaScript 平臺有很好的兼容性,都可用 Kotlin 寫代碼然后部署到你想要的地方:
import kotlin.browser.window
fun onLoad() {
window.document.body!!.innerHTML += "<br/>Hello, Kotlin!"
}
2.4 工具友好
可以用任何 Java IDE 或者使用命令行構(gòu)建。
3. Kotlin能做什么?
如果對 Kotlin 的能力僅僅停留在 JVM平 臺,那是片面的。如今的 Kotlin 已經(jīng)從當初的更好 Java 目標完成了它華麗的大變身,他們的目標已經(jīng)瞄準了星辰大海。目前 Kotlin 可以適用于移動端跨平臺、原生 JVM、服務端開發(fā)、Web 開發(fā)、Android 開發(fā)、數(shù)據(jù)科學等多個領域。此外近年來 Kotlin 團隊已經(jīng)將重心轉(zhuǎn)移到了語言層面的跨平臺,多平臺的支持。
另一方面,Kotlin 得益于 Kotlin/JVM、Kotlin/JS、Kotlin/Native 三個語言編譯器的后端實現(xiàn),它不僅僅可以編譯成 Java 字節(jié)碼(Kotlin/JVM),也可以編譯成JavaScript(Kotlin/JS),還能編譯成直接運行在不需要任何VM平臺的機器代碼(Kotlin/Native),可以輕松實現(xiàn)語言層面的跨平臺,并實現(xiàn)在多個平臺之間共享代碼。目前已經(jīng)部分支持了Linux、Windows、macOS、WebAssembly、Android、iOS以及watchOS和tvOS平臺。
4. 本教程能學到哪些 Kotlin 技能 ?
-
Kotlin的基本語法和代碼規(guī)范 ;
-
Kotlin的面向?qū)ο螅?/p>
-
Kotlin的函數(shù)式編程;
-
擴展函數(shù) ;
-
屬性代理 ;
-
空指針類型安全 ;
-
運算符重載 ;
-
lambda表達式和高階函數(shù);
-
類型系統(tǒng);
-
泛型和型變 ;
-
注解和反射 ;
-
協(xié)程的基本使用;
-
Kotlin 的 DSL;
-
Kotlin 高效實現(xiàn)常用的設計模式;
-
Kotlin 在 Android、IntelliJ IDEA 插件、Gradle、服務端、Web、iOS 等實際應用開發(fā)。
5. 本教程適合哪些人群?
-
零基礎的開發(fā)者(會從編程語言的最基礎開始講起);
-
有一定 Java、C 或 C++ 開發(fā)基礎開發(fā)者想學習 Kotlin 開發(fā);
-
Android 開發(fā)者想學習 Kotlin 開發(fā) Android 應用;
-
Java 后端開發(fā)者想學習 Kotlin 開發(fā)后端應用;
-
對 Kotlin 語言感興趣的所有開發(fā)者。
6. 總結(jié)幾條學習 Kotlin 的建議?
-
如果有 Java 編程基礎,記住千萬不要用 Java 編程思維來寫 Kotlin 代碼,換句話說不要硬生生把 Java 代碼轉(zhuǎn)化成 Kotlin 代碼來寫,更需要換個思維想如果用 Kotlin 某個語法糖實現(xiàn)的話更優(yōu)呢,否則將無法真正體會Kotlin這門語言精髓;
-
記住要善于使用 Kotlin 中的反編譯代碼插件,就是將 Kotlin 代碼反編譯成 Java 代碼。這是一條非常重要和實用的建議,通過它將會真正看透 Kotlin 語法糖背后原理,從而更高效地使用它;
-
學會經(jīng)常去看 Kotlin 源碼實現(xiàn),其實 Kotlin 源碼很短的,當知道如何使用某個語法,更需要知道它背后原理以及善于總結(jié)它適用的場景;
-
最后就是多多實踐,最好是自己弄個實際的項目,從0到1全部使用 Kotlin 開發(fā),每天一點一點給它舔磚加瓦,通過它來學習每一個 Kotlin 語法技能點。