Kotlin | 利用扩展函数转换对象的一个小技巧

有这么一种场景:当我们从服务端请求到数据并转换为实体对象后,UI 界面层需要的却是另一个实体类,比如实际项目场景中:

  • case1: 前者实体类是用 Java 编写的,而后者由于某些原因必须使用Kotlin编写的一个实体类,那么就要进行一次类型转换了;
  • case2: 前者实体类也是Kotlin 编写的,但是只是最终实体类的一部分数据,最终数据是由多个实体类组合起来的,那么同样需要进行一次类型转换。
  • ... ...

比如下面两个实体类:

kotlin 复制代码
@Serializable
data class A(
    val id: String,
    val name: String = "",
    val shortDescription: String = "",
    val longDescription: String = "",
    val url: String = "",
    val imageUrl: String = "",
)

data class B(
    val id: String,
    val name: String,
    val shortDescription: String,
    val longDescription: String,
    val url: String,
    val imageUrl: String,
    val followed: Boolean = false,
)

其中A是从服务端获取数据后生成的,而UI界面层使用的是B。如果不想多考虑,那么直接在new B()的时候,将A实例中需要的数据赋值给B实例中的变量即可:

kotlin 复制代码
val a: A = ......//假设从服务端生成了A实例
//将A实例中的数据传到B中
val b = B(
       id = a.id,
       name = a.name,
       shortDescription = a.shortDescription,
       longDescription = a.longDescription,
       url = a.url,
       imageUrl = a.imageUrl,
       followed = true, //followed从其他数据源获取
     )
//接下来就可以将b对象传到UI界面层进行使用了

不知道有没有小伙伴像上面这样使用,反正我写的时候都是直接转(此时必须要上那个经典配图了):

直到我在学习谷歌的一个Demo项目时,看到了这种写法:

kotlin 复制代码
//顶级A扩展函数,将其转换成B
fun A.asEntity() = B(
    id = id,
    name = name,
    shortDescription = shortDescription,
    longDescription = longDescription,
    url = url,
    imageUrl = imageUrl,
    followed = true,
)


//使用的地方,如在ViewModel中
suspend fun getA(ids: List<String>?): List<A>{
  ......
}
//1、第1个地方使用
val result1 : List<B> = network1.getA().map(A::asEntity)
//2、第2个地方使用
val result2 : List<B> = network2.getA().map(A::asEntity)

不得不说这种写法给人眼前一亮的感觉(可能有的大佬早就这样写了😁),A.asEntity()是一个顶级扩展函数,负责将A实例中的变量值赋给对应的B中,后续有修改可以统一在这里处理;另外顶级函数也意味着可以在任意有需要的地方调用它,比如上述示例的1、 2处都可以调用这个扩展函数,从而达到复用的目的。

之前分享过一篇: 提高开发效率!5个对开发者有用的Kotlin扩展函数,文章列举了一些比较实用的扩展函数,本文中也是扩展函数的一种使用,同样也是一种不错的选择。

相关推荐
Mr数据杨5 小时前
【Codex】用学生入学评估模块建立新生能力画像
android·java·javascript·django·codex·项目开发
●VON5 小时前
谁小时候不想要一个游戏修改器?我把电脑 Skill 做成了 Android 小助手
android·游戏·电脑
刃神太酷啦5 小时前
Linux 系统 MySQL 完整安装配置教程:从卸载 MariaDB 到优化 my.cnf----《Hello MySQL!》(1)
android·linux·c语言·c++·mysql·leetcode·mariadb
里欧跑得慢5 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
IT毕设实战小研6 小时前
基于安卓的空气质量查询系统
android·大数据·vue.js·爬虫·python·django·课程设计
雨声不在8 小时前
docker-android Android 16 支持与编译修改
android
天空之城--13 小时前
【无标题】
android
mmsx15 小时前
osmdroid 接入谷歌影像底图:瓦片 URL 拼接与多域名轮询实战
android·osmdroid
ZYJCSZKJ15 小时前
基于大语言模型的地域实体语义增强:生成式引擎优化(GEO)中的多模态内容生成实践
android·人工智能·语言模型
ssshooter15 小时前
Tauri + GitHub Actions 自动化发布 Android APK 技术总结
android·github·android studio