当前位置: 首页 > news >正文

kotlin中枚举带参数和不带参数的区别


✅ 代码对比总结

第一段(带参数 + 工具方法)

enum class SeatPosition(val position: Int) {DRIVER_LEFT(0),DRIVER_RIGHT(1),SECOND_LEFT(2),SECOND_RIGHT(3);companion object {fun fromPosition(position: Int): SeatPosition? {return SeatPosition.entries.find { it.position == position }}}
}

第二段(纯枚举,无参数)

enum class SeatPosition {DRIVER_LEFT,    // 主驾左 0DRIVER_RIGHT,   // 主驾右 1SECOND_LEFT,    // 二排左 2SECOND_RIGHT    // 二排右 3
}

🔍 差异分析

特性第一段第二段
是否有参数✅ 有 position: Int 参数❌ 无参数
成员是否绑定元数据✅ 每个枚举值绑定明确的编号❌ 没有编号,编号只能通过 ordinal 获取
可否自定义映射方法✅ 提供 fromPosition() 方法❌ 没有映射逻辑,只能手动判断
可扩展性✅ 更强:可以添加更多属性,如名称、图标等❌ 弱,只是纯枚举
Java 互操作性✅ 更明确的数据结构✅ 兼容,但参数为 ordinal
可维护性✅ 易维护映射关系、业务逻辑❌ 注释易失效,耦合不清晰

🛠 使用场景对比

场景第一段适用第二段适用
需要根据 Int 值查找枚举值✅ 非常适合,例如从网络/数据库解析位置编号❌ 需自己手动 whenordinal
枚举值需要额外信息(如文字、图标)✅ 适合扩展字段❌ 不支持直接扩展
只用于简单状态判断(如判断是否是主驾)✅ ✅ 都可以
性能敏感的场景✅ 略慢(多了字段)✅ 更轻量级
代码简洁优先❌(稍复杂)✅(更简洁)

📌 调用方式对比

第一段:

val seat = SeatPosition.fromPosition(2)
// 输出: SeatPosition.SECOND_LEFTval index = SeatPosition.DRIVER_LEFT.position
// 输出: 0

第二段:

val index = SeatPosition.DRIVER_LEFT.ordinal
// 输出: 0val seat = SeatPosition.values()[2]
// 输出: SeatPosition.SECOND_LEFT(注意越界风险)

✅ 建议总结:

  • 如果有明确的编号映射、需要从 Int 映射回枚举值 → 用第一段。
  • 如果只需要简单状态枚举,不关心映射逻辑 → 第二段更简洁。

二 枚举类中参数的作用

以下是对 enum class 中构造参数 val position: Int 作用的深入解释:


✅ 1. val position: Int 的作用是什么?

这是 枚举类的构造参数,用于在定义每个枚举值时传入特定的数据,例如:

enum class SeatPosition(val position: Int) {DRIVER_LEFT(0),DRIVER_RIGHT(1)
}

这里的 position: Int 是传入给构造函数的参数,用于为每个枚举值绑定一个 明确的编号。可以在枚举内部引用这个参数,比如在映射方法中查找使用:

fun fromPosition(pos: Int): SeatPosition? {return entries.find { it.position == pos }
}

✅ 2. 不写 val 行不行?

不写 valvar 是可以的,但有区别:

// 不写 val/var(这是合法的)
enum class SeatPosition(position: Int) {DRIVER_LEFT(0),DRIVER_RIGHT(1)
}

这会导致 position 是构造参数,但不是类成员变量无法在类外部或内部使用它,编译器会报错:

// ❌ 编译错误:Unresolved reference: position
fun test() {println(SeatPosition.DRIVER_LEFT.position)
}

✅ 3. 写了 val/var 是什么效果?

  • val position: Int:定义一个不可变的成员变量,可以在类内部和外部访问。
  • var position: Int:定义一个可变的成员变量(不推荐在枚举中使用,因为枚举值应该是常量)。
enum class SeatPosition(val position: Int) {DRIVER_LEFT(0)
}// ✅ 可直接访问
val p = SeatPosition.DRIVER_LEFT.position  // 输出:0

🧠 总结区别:

写法构造参数是否类成员是否能访问
SeatPosition(position: Int)✅ 是❌ 否❌ 无法访问
SeatPosition(val position: Int)✅ 是✅ 是(只读)✅ 可以访问
SeatPosition(var position: Int)✅ 是✅ 是(可写)✅(不推荐)

✅ 结论:

  • 如果只是想让每个枚举值带一个编号供逻辑使用,一定要加 val
  • 不加 val 只是传进构造函数但无法使用,一般没有意义。
  • 枚举中不建议使用 var,因为枚举值是常量,保持不可变更安全。

三 密封类使用场景

更复杂、更灵活的分支类型模型,使用密封类

“Kotlin 推荐使用密封类代替枚举类” —— 并不是绝对的推荐,而是取决于使用场景。

Kotlin 官方文档没有说密封类推荐替代枚举类,而是强调 密封类适用于更复杂、更灵活的分支类型模型(尤其适用于表达多态和不同状态)。我们来详细拆解这个话题。


✅ 核心区别回顾:enum class vs sealed class

特性enum class(枚举类)sealed class(密封类)
适合场景表示固定值集合(状态、选项)表示固定的类层级,但每个子类可以不同结构
成员定义所有成员结构相同每个子类可以结构、数据不同
多态性❌ 不支持多态(不能继承、不能添加行为)✅ 支持继承、多态
构造复杂数据❌ 不支持✅ 每个子类可带不同数据
示例颜色(RED、BLUE)网络响应(Success、Error)

✅ 为什么 Kotlin 有时建议使用密封类?

这是出现在 “有限状态 + 不同数据” 的使用场景下,传统 enum 做不到这一点

🔴 用 enum class 只能表示静态标签:

enum class NetworkState {SUCCESS,ERROR,LOADING
}

这个结构不能表示:出错时的错误信息、成功时的数据内容


✅ 用 sealed class 就能表达数据状态 + 数据内容:

sealed class NetworkResult<out T> {data class Success<T>(val data: T) : NetworkResult<T>()data class Error(val message: String) : NetworkResult<Nothing>()object Loading : NetworkResult<Nothing>()
}

可以这样用:

fun handle(result: NetworkResult<String>) {when (result) {is NetworkResult.Success -> println("Data: ${result.data}")is NetworkResult.Error -> println("Error: ${result.message}")is NetworkResult.Loading -> println("Loading...")}
}

这个功能是 enum class 无法实现的,因此在表达复杂状态、逻辑时,密封类是更推荐的做法


✅ 密封类的典型使用场景

  1. 状态管理(如 UI 状态、网络状态、流程控制):

    sealed class UiState {object Loading : UiState()data class Success(val data: String) : UiState()data class Error(val reason: String) : UiState()
    }
    
  2. 表达不同事件类型(如 ViewModel 中的 Event):

    sealed class UserEvent {object Login : UserEvent()data class ShowToast(val message: String) : UserEvent()
    }
    
  3. 组合型数据结构(代替多种接口实现)

    sealed class Shape {data class Circle(val radius: Double) : Shape()data class Rectangle(val width: Double, val height: Double) : Shape()
    }
    

✅ 结论

如果需要:选择
仅表示几个固定选项或状态(如座椅位置)enum class
表达状态 + 携带不同数据sealed class
多态、状态机模式、复杂条件匹配sealed class 更适合
轻量、简洁、不需要多态的enum class 更轻便

http://www.xdnf.cn/news/284221.html

相关文章:

  • Debezium MySqlValueConverters详解
  • 抖音生活服务“五一”数据:小城游火爆,“食住”消费增速显著
  • 【Game】Powerful——Transformation Card(10)
  • linux系统基本操作命令
  • 探索神经符号系统:医疗AI的范式化进程分析
  • # 从零构建一个简单的卷积神经网络:手写数字识别
  • HTML 元素
  • adb无线调试步骤
  • MySQL C API高效编程:C语言实现数据库操作的深入解析
  • Git 第一讲---基础篇 git基础概念与操作
  • 《MATLAB实战训练营:从入门到工业级应用》高阶挑战篇-《用无人机仿真玩转PID控制:MATLAB四旋翼仿真建模全攻略》
  • MATLAB人工大猩猩部队GTO优化CNN-LSTM多变量时间序列预测
  • CDN一般在什么情况下会出现402报错呢?
  • 详解RabbitMQ工作模式之路由模式
  • Java后端开发day41--IO流(一)--FileOutputStreamFileInputStream
  • React-router v7 第八章(边界处理)
  • tensorflow 调试
  • Python从入门到高手8.2节-元组的常用操作符
  • 【Leetcode 每日一题 - 补卡】838. 推多米诺
  • LeetCode 热题 100 78. 子集
  • HTML5好看的水果蔬菜在线商城网站源码系列模板9
  • Nginx正反向代理与正则表达式
  • jupyter notebook运行简单程序
  • Linux:深入理解数据链路层
  • Linux 入门:操作系统进程详解
  • Javase 基础加强 —— 01 异常
  • Java高并发处理核心技术详解:从理论到实战
  • 「一针见血能力」的终极训练手册
  • python全自动爬取m3u8网页视频(各类网站都通用)
  • 百度「心响」:左手“多智能体”右手“保姆级服务”,C端用户能看懂这技术告白吗?