Kotlin的密封数据类

FRR*_*FRR 8 kotlin

我有以下密封课程

sealed class DownloadWallpaper : Result() {
    data class Progress(val hd: Boolean = false, ...) : DownloadWallpaper() 
    data class Success(val hd: Boolean = false, ...) : DownloadWallpaper()
    data class Error(val hd: Boolean = false, ...) : DownloadWallpaper()
}
Run Code Online (Sandbox Code Playgroud)

我正在努力做到以下几点.

//obs is of type Observable<Detail.Result.DownloadWallpaper> 
obs.map{ it.copy(hd = true) }
Run Code Online (Sandbox Code Playgroud)

但我不能,因为两个原因,因为DownloadWallpaper不是数据类.没有.copy()方法.我怎么能告诉Kotlin这个印章类的所有课程实际上都是data classes

其次,DownloadWallpaper它自己没有'hd'字段.我可以使用什么时候如何优雅地解决这个问题?这个解决方案非常难看:

when (it) {
           is Detail.Result.DownloadWallpaper.Success -> it.copy(hd = true)
           is Detail.Result.DownloadWallpaper.Progress -> it.copy(hd = true)
           is Detail.Result.DownloadWallpaper.Error -> it.copy(hd = true)
 }
Run Code Online (Sandbox Code Playgroud)

Sim*_*mY4 10

通过向密封类添加一些抽象方法,我能够访问复制方法而无需显式类型检查.你自己看:

sealed class DownloadWallpape {
    abstract val hd: Boolean
    abstract fun copy(hd: Boolean): DownloadWallpape
}

data class Progress(override val hd: Boolean = false, val a: Any) : DownloadWallpape() {
    override fun copy(hd: Boolean) = copy(hd = hd, a = a)
}
data class Success(override val hd: Boolean = false, val s: String) : DownloadWallpape() {
    override fun copy(hd: Boolean) = copy(hd = hd, s = s)
}
data class Error(override val hd: Boolean = false, val c: Int) : DownloadWallpape() {
    override fun copy(hd: Boolean) = copy(hd = hd, c = c)
}

fun main() {
    val dw: DownloadWallpape = Progress()
    val newDw = dw.copy(hd = false)
    val newDwSameHd = dw.copy(hd = dw.hd)
}
Run Code Online (Sandbox Code Playgroud)

  • 这是密封类的一个伟大但被遗忘的功能。由于类型铸造的减少,它有助于减少样板代码。它应该是密封类中的默认值,而不需要抽象类。 (4认同)