精簡的 data class 及 Parcelize:在 Java 的開發環境中,你需要為每一個資料欄位補上 setter, getter 及其他需要的函式,且在 Android 中如果需要在 activity 或 fragment 中傳遞資料,你還必須實作 Parcelable,則需要覆寫的函數就更多了。在 Kotlin 中一樣提供 Android 開發者簡潔有力的資料類別,直接看範例就能體會到精簡多少程式碼了!
Java
Kotlin
public class Person implements Parcelable {
private int age;
private String name;
protected Person(Parcel in) {
age = in.readInt();
name = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator CREATOR = new Creator() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
@Parcelize
data class Person(
val age: Int,
val name: String
) : Parcelable
初始化物件:Kotlin 提供了需多便利的擴展函數,像是 apply, let, with, run, also 等等。這邊針對 Android 開發,我想特別提到關於物件初始化時 Kotlin 相對於 Java 更直覺且簡潔的語法,身為工程師一樣看程式碼解釋一切:
Java
Kotlin
TextView textViewDescription = new TextView(this);
textViewDescription.setText(Html.fromHtml(article.content));
textViewDescription.setEnabled(article.isSupported());
textViewDescription.setMovementMethod(LinkMovementMethod.getInstance());
val textViewDescription = TextView(this).apply {
text = article.content.toSpanned()
isEnabled = article.isSupported()
movementMethod = LinkMovementMethod.getInstance()
}
Default And Named Arguments:Kotlin 的函數參數可以擁有預設值以及指定參數名稱,當省略傳入相應的參數值時將使用預設值。而這相較於其他語言,將大大減少 overloading function 的數量。
Kotlin
// api interface
fun getComments(
id: String,
commentSize: Int = 15,
parentCommentSn: String? = null,
ccCookie: String? = null,
sort: SortCategory = SortCategory.POPULAR,
direction: Direction = Direction.DESC
): Single
// usage
apiClient.getComments(id = articleId)
apiClient.getComments(id = articleId, sort = LATEST, ccCookie = ccCookie)
Higher-Order Functions And Lambda:高階函數是一種特殊的函數,這種函數接受函數作為參數,也能返回函數當作結果。這邊以 Android 常見的 UI component作為範例,在實作recyclerview 時總是要傳入 onClickListener 給 Adapter 來操作點擊後的動作。這時候如果直接把 onClick function 搭配 lambda 表示式來當作參數傳入,程式碼便又能精簡很多。
Kotlin
// pass function as an argument
class SearchResultAdapter(
private val onArticleClickAction: (Int, SearchedArticle) -> Unit
) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
ArticleViewHolder(inflatedView).listen { position, article ->
onArticleClickAction(position, view.tag as SearchedArticle)
}
}
// lambda usage
private val resultAdapter: SearchResultAdapter =
SearchResultAdapter { _, article ->
startActivity(ArticleActivity.createIntent(context, article.url))
}