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

news2025/5/10 12:09:23


✅ 代码对比总结

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

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,    // 主驾左 0
    DRIVER_RIGHT,   // 主驾右 1
    SECOND_LEFT,    // 二排左 2
    SECOND_RIGHT    // 二排右 3
}

🔍 差异分析

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

🛠 使用场景对比

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

📌 调用方式对比

第一段:

val seat = SeatPosition.fromPosition(2)
// 输出: SeatPosition.SECOND_LEFT

val index = SeatPosition.DRIVER_LEFT.position
// 输出: 0

第二段:

val index = SeatPosition.DRIVER_LEFT.ordinal
// 输出: 0

val 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.coloradmin.cn/o/2372287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux进程控制一】进程的终止和等待

【Linux进程控制一】进程的终止和等待 一、进程终止1.main函数的return2.strerror函数3.库函数exit4.系统调用_exit和库函数exit的区别5.异常信号6.变量errno 二、进程等待1.什么是进程等待&#xff1f;2.wait接口3.status4.waitpid接口 一、进程终止 1.main函数的return 写C…

今日行情明日机会——20250509

上证指数今天缩量&#xff0c;整体跌多涨少&#xff0c;走势处于日线短期的高位~ 深证指数今天缩量小级别震荡&#xff0c;大盘股表现更好~ 2025年5月9日涨停股主要行业方向分析 一、核心主线方向 服装家纺&#xff08;消费复苏出口链驱动&#xff09; • 涨停家数&#xf…

单片机-STM32部分:10、串口UART

飞书文档https://x509p6c8to.feishu.cn/wiki/W7ZGwKJCeiGjqmkvTpJcjT2HnNf 串口说明 电平标准是数据1和数据0的表达方式&#xff0c;是传输线缆中人为规定的电压与数据的对应关系&#xff0c;串口常用的电平标准有如下三种&#xff1a; TTL电平&#xff1a;3.3V或5V表示1&am…

RabittMQ-高级特性2-应用问题

文章目录 前言延迟队列介绍ttl死信队列存在问题延迟队列插件安装延迟插件使用事务消息分发概念介绍限流非公平分发&#xff08;负载均衡&#xff09; 限流负载均衡RabbitMQ应用问题-幂等性保障顺序性保障介绍1顺序性保障介绍2消息积压总结 前言 延迟队列介绍 延迟队列(Delaye…

React 播客专栏 Vol.5|从“显示”到“消失”:打造你的第一个交互式 Alert 组件!

&#x1f44b; 欢迎回到《前端达人 播客书单》第 5 期&#xff08;正文内容为学习笔记摘要&#xff0c;音频内容是详细的解读&#xff0c;方便你理解&#xff09;&#xff0c;请点击下方收听 &#x1f4cc; 今天我们不再停留在看代码&#xff0c;而是动手实现一个真正的 React…

解密火星文:LeetCode 269 题详解与 Swift 实现

文章目录 摘要描述题解答案题解代码分析构建图&#xff08;Graph&#xff09;拓扑排序&#xff08;Topological Sort&#xff09; 示例测试及结果时间复杂度空间复杂度实际场景类比总结 摘要 这篇文章我们来聊聊 LeetCode 269 题&#xff1a;火星词典&#xff08;Alien Dictio…

动态规划-62.不同路径-力扣(LeetCode)

一、题目解析 机器人只能向下或向左&#xff0c;要从Start位置到Finish位置。 二、算法原理 1.状态表示 我们要求到Finish位置一共有多少种方法&#xff0c;记Finish为[i,j]&#xff0c;此时dp[i,j]表示&#xff1a;到[i,j]位置时&#xff0c;一共有多少种方法&#xff0c;满…

5月9号.

v-for: v-bind: v-if&v-show: v-model: v-on: Ajax: Axios: async&await: Vue生命周期: Maven: Maven坐标:

从 Git 到 GitHub - 使用 Git 进行版本控制 - Git 常用命令

希望本贴能从零开始带您一起学习如何使用 Git 进行版本控制&#xff0c;并结合远程仓库 GitHub。这会是一个循序渐进的指南&#xff0c;我们开始吧&#xff01; 学习 Git 和 GitHub 的路线图&#xff1a; 理解核心概念&#xff1a;什么是版本控制&#xff1f;Git 是什么&…

双指针算法详解(含力扣和蓝桥杯例题)

目录 一、双指针算法核心概念 二、常用的双指针类型&#xff1a; 2.1 对撞指针 例题1&#xff1a;盛最多水的容器 例题2&#xff1a;神奇的数组 2.2 快慢指针&#xff1a; 例题1&#xff1a;移动零 例题2&#xff1a;美丽的区间&#xff08;蓝桥OJ1372&#xff09; 3.总…

【网络编程】二、UDP网络套接字编程详解

文章目录 前言Ⅰ. UDP服务端一、服务器创建流程二、创建套接字 -- socketsocket 属于什么类型的接口❓❓❓socket 是被谁调用的❓❓❓socket 底层做了什么❓❓❓和其函数返回值有没有什么关系❓❓❓ 三、绑定对应端口号、IP地址到套接字 -- bind四、数据的发送和接收 -- sendto…

【应急响应】- 日志流量如何分析?

【应急响应】- 日志流量如何下手&#xff1f;https://mp.weixin.qq.com/s/dKl8ZLZ0wjuqUezKo4eUSQ

djinn: 3靶场渗透

djinn: 3 来自 <https://www.vulnhub.com/entry/djinn-3,492/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.243 3&#xff0…

VS Code配置指南:打造高效的QMK开发环境

VS Code配置指南&#xff1a;打造高效的QMK开发环境 前言 你是否曾为QMK固件开发环境的搭建而头疼不已&#xff1f;本文将手把手教你使用Visual Studio Code&#xff08;简称VS Code&#xff09;这款强大的代码编辑器来构建一个完美的QMK开发环境&#xff0c;让你的键盘固件开…

服务器多客户端连接核心要点(1)

刷题 服务器多客户端连接核心要点 多进程服务器 实现原理 fork子进程&#xff1a;每次accept新客户端后&#xff0c;调用fork创建子进程。独立处理&#xff1a;子进程负责与客户端通信&#xff08;如read/write&#xff09;&#xff0c;父进程继续监听新连接。 特点 隔离性…

Stagehand:AI驱动的下一代浏览器自动化框架

Stagehand 是一个结合了 AI 代理、AI 工具和 Playwright 的浏览器自动化框架。核心理念是&#xff1a;让自动化任务既可控又智能。与传统工具不同&#xff0c;Stagehand 不仅仅依赖 AI 代理的“黑箱操作”&#xff0c;而是通过与 Playwright 的深度结合&#xff0c;赋予开发者对…

爱普生FA-238在车身控制模块中的应用

在汽车智能化、电子化飞速发展的当下&#xff0c;车身控制模块&#xff08;BCM&#xff09;作为车辆的 “智能管家”&#xff0c;肩负着协调和控制众多车身功能的重任&#xff0c;从车门的解锁与锁定、车窗的升降&#xff0c;到车灯的智能点亮与熄灭&#xff0c;再到雨刮器的自…

【A2A】管中窥豹,google源码python-demo介绍

前言 A2A&#xff08;Agent2Agent&#xff09;是 Google 推出的一项新协议&#xff0c;旨在解决多智能体&#xff08;Multi-Agent&#xff09;系统中跨平台、跨组织协作的难题。它为 AI 代理之间的通信、协作和任务分工提供了一个统一的标准&#xff0c;可以类比为网页世界的 H…

004-nlohmann/json 快速认识-C++开源库108杰

了解 nlohmann/json 的特点&#xff1b;理解编程中 “数据战场”划分的概念&#xff1b;迅速上手多种方式构建一个JSON对象&#xff1b; 1 特点与安装 nlohmann/json 是一个在 github 长期霸占 “JSON” 热搜版第1的CJSON处理库。它的最大优点是与 C 标准库的容器数据&#xf…

Matlab实现CNN-BiLSTM时间序列预测未来

Matlab实现CNN-BiLSTM时间序列预测未来 目录 Matlab实现CNN-BiLSTM时间序列预测未来效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CNN-BiLSTM时间序列预测未来&#xff1b; 2.运行环境Matlab2023b及以上&#xff0c;data为数据集&#xff0c;单变量时间序…