Kotlin
Parcelable

解決擁有單一 Parcelable 參數的建構子和 Parcel 用建構子同時存在時導致無法判定該使用哪個的問題

More than 1 year has passed since last update.

背景

我有個 Parcelable 型別,他的建構子有一個有擴充 Parcelable 的參數,像是這樣:

Product.kt
// package 略
// import 略

data class Product(val id: String, val name: String): Parcelable {
    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString())

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(id)
        parcel.writeString(name)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<Product> {
        override fun createFromParcel(parcel: Parcel): Product = Product(parcel)
        override fun newArray(size: Int): Array<Product?> = arrayOfNulls(size)
    }
}
Presenter.kt
// package 略
// import 略

class Presenter(val product: Product): Parcelable {
    constructor(parcel: Parcel) : this(
            parcel.readParcelable(Product::class.java.classLoader))

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeParcelable(product, flags)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<Presenter> {
        override fun createFromParcel(parcel: Parcel): Presenter = Presenter(parcel)
        override fun newArray(size: Int): Array<Presenter?> = arrayOfNulls(size)
    }
}

無法判定該使用哪個建構子

這時候出現在這個地方

constructor(parcel: Parcel) : this(
        parcel.readParcelable(Product::class.java.classLoader))

出了一個錯誤:

Overload resolution ambiguity. All these functions match.
- public constructor Presenter(parcel: Parcel) defined in my.package.Presenter
- public constructor Presenter(product: Product) defined in my.package.Presenter

原因是 Product 的物件要放進來,因為他本身也是 Parcelable ,所以在這兩個建構子都可以使用的情形之下,導致 IDE 發出錯誤訊息說他不知道該用哪一個建構子。

解決方法 - Named Arguments

當在使用 Kotlin 的函式的時候,可以在前面加上參數的名稱,增加呼叫時的可讀性
所以在這個時候,只要指定說,我是要用 Product 的那個建構子即可。

所以那段程式碼可以這樣改:

constructor(parcel: Parcel) : this(
        product = parcel.readParcelable(Product::class.java.classLoader))

這樣子就可以解決錯誤提醒並正常運行了!

參考