Kotlin中如何根据输入参数动态决定变量类型消除重复代码
实现方案
Kotlin是静态类型语言,变量的声明类型在编译期就必须确定,不存在运行时动态切换变量类型的语法,你设想的那种在变量声明后直接跟if/else切类型的写法本身就不支持。要消除重复分支逻辑,最稳妥、性能最好、类型安全的做法是抽象公共行为契约,完全不需要写冗余的重复代码。
步骤1:抽离公共接口
你所有的Point类都会调用findDistanceFromOrigin()方法,初始化逻辑也一致,先把这些公共行为定义成统一接口:
import kotlin.math.sqrt // 公共接口,约定所有点类型必须实现的公共方法 interface DistanceCalculable { fun findDistanceFromOrigin(): Double } // 所有业务用到的点类型都实现这个接口 data class Point2D(val x: Int, val y: Int) : DistanceCalculable { override fun findDistanceFromOrigin(): Double { return sqrt((x * x + y * y).toDouble()) } } class Point2DWithP1AsOrigin(val x: Int, val y: Int) : DistanceCalculable { override fun findDistanceFromOrigin(): Double { // 替换为以P1为原点的实际距离计算逻辑 val originX = 0 val originY = 0 return sqrt(((x - originX) * (x - originX) + (y - originY) * (y - originY)).toDouble()) } } class Point2DWithP2AsOrigin(val x: Int, val y: Int) : DistanceCalculable { override fun findDistanceFromOrigin(): Double { // 替换为以P2为原点的实际距离计算逻辑 val originX = 100 val originY = 100 return sqrt(((x - originX) * (x - originX) + (y - originY) * (y - originY)).toDouble()) } }
步骤2:用when表达式做类型映射,合并重复逻辑
用Kotlin内置的when表达式替代冗长的if-else链,根据输入直接返回对应类型的实例——因为所有实例都实现了公共接口,变量类型会自动推导为统一的接口类型,后续的计算、返回逻辑只需要写一次:
fun compute(input: String): Any { // 统一用接口类型接收实例,不需要为每个分支单独声明变量 val point: DistanceCalculable = when (input) { "2d" -> Point2D(x = 10, y = 20) // 替换为实际初始化参数 "2d-1" -> Point2DWithP1AsOrigin(x = 10, y = 20) "2d-2" -> Point2DWithP2AsOrigin(x = 10, y = 20) else -> throw IllegalArgumentException("不支持的输入标识:$input") } // 所有分支重复的初始化、计算、返回逻辑只需要写这一次 // 其他公共计算逻辑可直接在此处补充 return point.findDistanceFromOrigin() }
不推荐用反射实现动态类型的原因
如果硬要实现你示例里写的传KClass动态创建实例的效果,只能靠反射,但这种做法有两个明显缺陷:
- 丢失编译期类型检查:如果类没有匹配的构造方法、或者缺失
findDistanceFromOrigin方法,要到运行时才会抛错,很容易引发线上问题 - 反射本身有额外性能开销,代码可读性和可维护性也差
完全没必要为了省几行接口定义代码用反射。如果你的Point类是第三方依赖提供的、没法直接修改源码让它实现接口,写个包装类做适配即可,核心逻辑和上述方案一致。
内容的提问来源于stack exchange,提问作者Light Yagami
相关产品推荐
相关产品推荐

