gpt4 book ai didi

android - 我如何使用密封类来描述具有关联值的有限案例集,以及更小的此类值集?

转载 作者:行者123 更新时间:2023-12-02 12:21:31 26 4
gpt4 key购买 nike

我正在考虑使用密封类来表示一组有限的可能值。

这是代码生成项目的一部分,该项目将编写大量此类,每个类都有很多案例。因此,我担心应用程序的大小。由于多个案例很可能具有相同的属性,因此我正在考虑使用包装器,例如:

data class Foo(val title: String, ...lot of other attributes)
data class Bar(val id: Int, ...lot of other attributes)

sealed class ContentType {
class Case1(val value: Foo) : ContentType()
class Case2(val value: Bar) : ContentType()

// try to reduce app size by reusing the existing type,
// while preserving the semantic of a different case
class Case3(val value: Bar) : ContentType()
}

fun main() {
val content: ContentType = ContentType.Case1(Foo("hello"))
when(content) {
is ContentType.Case1 -> println(content.value.title)
is ContentType.Case2 -> println(content.value.id)
is ContentType.Case3 -> println(content.value.id)
}
}

这是我应该如何解决这个问题吗?

如果是这样,我怎样才能最好地使密封类可以访问关联值的属性?这样

        is ContentType.Case2 -> println(content.value.id)

成为

        is ContentType.Case2 -> println(content.id)

最佳答案

Is this how I should approach this problem?

恕我直言,是的,但有一些语义变化,列在后面。

How can I best make the properties of the associated value accessible from the sealed class?

您可以为每个子类生成扩展或实例函数。

例如

val ContentType.Case2.id: String get() = value.id

这样就可以成功调用:

is ContentType.Case2 -> println(content.id)

How can I reduce the app size while preserving the semantic of another case?

您可以只为所有需要与参数类型相同的情况生成一个类,并使用 Kotlin contracts 来处理它们。

以您的示例为例,您可以生成:

sealed class ContentType {
class Case1(val value: Foo) : ContentType()
class Case2_3(val value: Bar, val caseSuffix: Int) : ContentType()
}

如您所见,类 Case2Case3 现在只是一个类,caseSuffix 标识它是其中的哪一个。

您现在可以生成以下扩展(每种情况一个):

@OptIn(ExperimentalContracts::class)
fun ContentType.isCase1(): Boolean {
contract {
returns(true) implies (this@isCase1 is ContentType.Case1)
}
return this is ContentType.Case1
}

@OptIn(ExperimentalContracts::class)
fun ContentType.isCase2(): Boolean {
contract {
returns(true) implies (this@isCase2 is ContentType.Case2_3)
}
return this is ContentType.Case2_3 && caseSuffix == 2
}

@OptIn(ExperimentalContracts::class)
fun ContentType.isCase3(): Boolean {
contract {
returns(true) implies (this@isCase3 is ContentType.Case2_3)
}
return this is ContentType.Case2_3 && caseSuffix == 3
}

由于您正在使用契约(Contract),客户现在可以将它们用于:

when {
content.isCase1() -> println(content.title)
content.isCase2() -> println(content.id)
content.isCase3() -> println(content.id)
}

如您所见,进一步的优化可能是为只有一个后缀的案例删除属性 caseSuffix 以避免不必要的属性。

关于android - 我如何使用密封类来描述具有关联值的有限案例集,以及更小的此类值集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60678654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com