kotlin - 有没有办法在 DocumentSnapshot.toObject() 中添加类型转换?
问题描述
我想让我的 Kotiln 应用程序与我的 Firestore 组件的耦合度降低。
我有一个曾经看起来像这样的模型:
data class MyObjectModel(
@DocumentId val id: String = "",
var title: String = "",
var media: List<String> = listOf()
)
由于它在应用程序中被广泛使用,它与 Firestore 非常耦合(例如,媒体列表应该是 url,我只使用字符串是因为 DocumentSnapshot.toObject() 有趣的限制)。我读到 Kotlin 数据类在继承方面存在很大问题,所以我想制作一个这样的接口:
interface MyObject{
val id: String
var title: String
val media: MutableList<Uri>
}
并在整个应用程序中使用它。
为了从 Firestore 获取对象,我想构建一个实现该接口的 POJO,如下所示:
data class MyObjectPojo(
@DocumentId override val id: String,
override var title: String,
override val media: MutableList<Uri>
) : MyObject {
constructor(id: String, title: String, media: List<String>) :
this(id, title, media.map { Uri.parse(it) } as MutableList<Uri>)
}
我发现这是不可能的,原因有两个:
- 第二个构造函数给出错误:“平台声明冲突:以下声明具有相同的 JVM 签名 ((Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V):...”
- 该
DocumentSnapshot.toObject()
函数仅调用主构造函数,这在我的情况下不起作用(因为它不支持将字符串自动解析为 Uris)
此外,随着我的对象将拥有更多的领域,这将成为很多样板......
我想到了一个解决方案:删除第二个构造函数并将第一个构造函数的最后一个参数从override val media: MutableList<Uri>
更改为val mediaStringList: MutableList<String>
。比我可以在类主体中执行以下操作之一:
// Solution 1
override val media: MutableList<Uri>
get() = mediaStringList.map { Uri.parse(it) } as MutableList<Uri>
// Solution 2
override val media = mediaStringList.map { Uri.parse(it) } as MutableList<Uri>
两者都很丑,因为第一个意味着每个 get 调用的列表映射操作,第二个意味着持有列表两次。如果我可以向构造函数添加一个主体,我将能够val
从mediaStringList
参数中删除,但我想根据主构造函数的定义这是不可能的......
我现在看到的唯一方法是实现toMyObject()
我自己的函数,但这也意味着为set()
函数实现另一种方式——我真的很想避免对我拥有的每个对象都这样做。还有其他方法可以解决这个问题吗?
解决方案
推荐阅读
- jakarta-ee - Wildfly多个war文件实现一个接口:如何获取实现?
- sql-server - Report Builder Sum IF 根据组
- python - 如何浏览查询结果并写入行(跳过重复)?
- sql - 从表中获取员工和经理的统计数据
- php - 如何从苗条的中间件中获取属性
- awk - 用 awk 替换 " by '
- sql-server - SQL Server - 大容量插入 - FIELDQUOTE 无法识别双引号
- python - 根据python中的条件检查执行路径
- node.js - 导出已解决的承诺结果
- prometheus - 普罗米修斯查询中来自grafana变量的多个值