kotlin - 使用地图重构 kotlin 中的“何时”逻辑
问题描述
我目前正在重构一些 Kotlin 代码 - 我有一个很好的解决方案来进行简单的重构,但不确定如何在 Koltin 语法中使用映射来做到这一点。任何帮助都会很棒!
当前代码
这是我的数据类:
public sealed class DocumentBody {
public data class Information(
val Id: String,
val name: String,
val sort: Int = 2
) : DocumentBody ()
public data class Location(
val name: String,
val address: String? = null,
val sort: Int = 3
) : DocumentBody()
public data class Rating(
val name: String,
val rating: Int,
val sort: Int = 3
) : DocumentBody()
}
目前在我的代码库中有一个扩展函数,它可以根据上下文类型获取一些扩展信息,这是:
private fun DocumentBody.getExtendedInfo(
settings: Settings = Settings()
): String? {
return if (settings.versions != null) {
when (this) {
is DocumentBody.Information ->
getExtentedInfo(ContentType.Information, settings.versions)
is DocumentBody.Location ->
getExtentedInfo(ContentType.Location, settings.versions)
is DocumentBody.Rating ->
getExtentedInfo(ContentType.Rating, settings.versions)
}
} else {
when (this) {
is DocumentBody.Information ->
ExtentedInfo[ContentType.Information]
is DocumentBody.Location ->
ExtentedInfo[ContentType.Location]
is DocumentBody.Rating ->
ExtentedInfo[ContentType.Rating]
}
}
重构代码
当寻找更好的方法来做到这一点时,我已经为 DocumentBody 类型创建了一个映射到 ContextType 像这样(不能为此在映射中设置类型 - 这可能是问题但不确定):
public val getContentTypeFromDocumentBody: Map<Any, ContentType> = mapOf(
DocumentBody.Information to ContentType.Information,
DocumentBody.Location to ContentType.Location,
DocumentBody.Rating to ContentType.Rating
)
在这里,我希望能够调用它并从键中获取 ContentType:
getContentTypeFromDocumentBody[docBodyType]
这目前正在通过数据,但我想要类型。我已经探索了如何用这样的想法来做到这一点:
private fun DocumentBody.getExtendedInfo(settings: Settings = Settings()): String {
getContentTypeFromDocumentBody.keys.map { docBodyType ->
when (this) {
is docBodyType -> getContentTypeFromDocumentBody[docBodyType]
else -> error("invalid document type")
}
}
}
但这不起作用,并且 creat 在第 4 行的 docBodyType 下有红线。
基本上我想将 DocumentBody 的类型传递到这个新地图中以获得内容类型,希望我想要做的这个想法是有意义的。任何帮助都会很棒!
解决方案
在我回答您的实际问题之前,我不得不说简单地将 ContentType 设为 DocumentBody 的属性会更直接,如下所示:
public sealed class DocumentBody(val contentType: ContentType) {
public data class Information(
val Id: String,
val name: String,
val sort: Int = 2
) : DocumentBody(ContentType.Information)
public data class Location(
val name: String,
val address: String? = null,
val sort: Int = 3
) : DocumentBody(ContentType.Location)
public data class Rating(
val name: String,
val rating: Int,
val sort: Int = 3
) : DocumentBody(ContentType.Rating)
}
我建议执行上述操作,但要回答您的问题,您不能简单地列出类名,就好像它们是某物的实例一样。您需要使用::class
来获取要传递的实际对象:
public val getContentTypeFromDocumentBody: Map<KClass<out DocumentBody>, ContentType> = mapOf(
DocumentBody.Information::class to ContentType.Information,
DocumentBody.Location::class to ContentType.Location,
DocumentBody.Rating::class to ContentType.Rating
)
然后使用::class
您要与之比较的对象的 进行检查:
private fun DocumentBody.getExtendedInfo(settings: Settings = Settings()): String {
val contentType = getContentTypeFromDocumentBody[this::class]
?: error("invalid document type")
//...
}
我还建议给你的地图一个描述性的名称,而不是让它听起来像一个 getter 函数。类似的东西contentTypeByDocumentBodyClass
。
推荐阅读
- chef-infra - 将配方和数据包复制到另一个实例
- php - PHP 如何获取特定的 JSON 值/参数
- django - pytest django:无法在夹具拆解中访问数据库
- regex - 仅匹配第一次出现
- if-statement - 此模式的适当逻辑
- c# - 从 RegionInfo.TwoLetterISORegionName 获取 CultureInfo
- c# - c#动态调用函数,没有if else
- php - 使用 PHP 转换 JSON 数组中的 Curl 响应字符串
- swift - 如何先从 URL 下载音频文件,然后播放所有
- python - Django 在 AJAX 调用中不接受 GET 输入