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.pswp.cn/web/78536.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/78536.shtml

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

相关文章

Java使用JDBC操作数据库

1.创建一个数据库一会用来连接 2.使用idea新建一个Java项目 3.在pom文件中加上相关依赖&#xff0c;并配置Maven路径 <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>…

重名导致does not name a type

今天在Ubuntu24.04上编成时&#xff0c;makefile编译报错: falsecolor.h:48:9: error: ‘FalseColor’ does not name a type48 | FalseColor* content ;| ^~~~~~~~~~falsecolor.h的部分代码如下: class FalseColor {public:FalseColor(int w, int h){width …

Vue3 后台管理系统模板

Vue3 后台管理系统模板 gie仓库地址 一个基于 Vue3 TypeScript Element Plus 的后台管理系统模板&#xff0c;集成了动态路由和权限管理功能。 技术栈 Vue 3.2TypeScript 4.5Vue Router 4Vuex 4Element Plus 2.9AxiosLess 功能特性 &#x1f680; 基于 Vue3 最新技术栈开…

林业数智化转型初步设计方案

最近应林业方面的朋友要求,帮助其设计了林业方面的数字化智能化转型的方案设计,编写了如下内容,供大家参考,林业方面主要有三大方向,即林业生态、生物灾害和疫源疫病,目前已经建成了一些信息化系统,但在数字化智能化方面偏弱,就想着如何借助人工智能、物联网、大数据和…

springboot单体项目的执行流程

首先就是启动springboot项目&#xff0c;即执行主函数&#xff0c;这个主函数的类通常带有SpingBootApplication注解&#xff0c;类中的main方法就是程序的入口。 启动主函数后&#xff0c;SpringBoot会按特定顺序加载配置文件&#xff0c;如application.properties或applicat…

Python格式化字符串的四种方法

Python格式化字符串的四种方法 1.使用 % 运算符 %s 是一个字符串的占位符&#xff0c;而 “World” 是替换它的值 print("Hello, %s!" % "World") # 输出&#xff1a;Hello, World!你可以使用多个占位符 注意&#xff1a;多个变量占位&#xff0c;变量要…

【Redis】缓存|缓存的更新策略|内存淘汰策略|缓存预热、缓存穿透、缓存雪崩和缓存击穿

思维导图&#xff1a; Redis最主要的用途&#xff0c;三个方面&#xff1a; 1.存储数据&#xff08;内存数据库&#xff09; 2.缓存&#xff08;redis最常用的场景&#xff09; 3.消息队列 一、什么是缓存 我们知道对于硬件的访问速度来说&#xff0c;通常情况下&#xff1…

中阳视角下的趋势确认策略:以数据为核心的交易思维

中阳视角下的趋势确认策略&#xff1a;以数据为核心的交易思维 在动态交易市场中&#xff0c;如何在波动中捕捉相对确定的趋势&#xff0c;是每一位操作者关心的问题。“中阳”理念主张通过结构性价格分析&#xff0c;判断市场情绪的拐点。尤其是在出现大阳线或中阳线时&#x…

【C/C++】inline关键词

C inline 关键字学习笔记 一、什么是 inline 函数&#xff1f; inline&#xff08;内联&#xff09;是 C 中的一个关键字&#xff0c;表示“将函数的代码直接插入到调用点”&#xff0c;以减少函数调用开销&#xff0c;提升执行效率。 ✅ 注意&#xff1a;inline 是一种“请求…

React useMemo函数

第一个参数是回调函数&#xff0c;返回计算的结果&#xff0c;第二个参数是依赖项&#xff0c;该函数只监听count1变量的变化 import { useReducer, useState } from react; import ./App.css;// 定义一个Reducer函数 根据不同的action进行不同的状态修改 function reducer(st…

对比测评:为什么AI编程工具需要 Rules 能力?

通义灵码 Project Rules 在开始体验通义灵码 Project Rules 之前&#xff0c;我们先来简单了解一下什么是通义灵码 Project Rules&#xff1f; 大家都知道&#xff0c;在使用 AI 代码助手的时候&#xff0c;有时候生成的代码不是自己想要的&#xff0c;或者说生成的代码采纳后…

Java学习手册:MyBatis 框架作用详解

一、MyBatis 简介 MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发。它通过将 Java 对象与数据库表之间的映射关系进行配置&#xff0c;使得开发者可以使用简单的 SQL 语句和 Java 代码来完成复杂的数据操作。MyBatis 支持自定义 SQL 语句&#xff0c;提供了灵…

list的设计

#pragma once #include<assert.h> #include<iostream> using namespace std; namespace aqc {template<class T>struct list_node{list_node* _next;list_node* _prev;T _data;list_node(const T& xT())//加const防止权限放大&#xff0c;用引用减少拷贝…

基于 PyQt 的YOLO目标检测可视化界面+ nuitka 打包

在人工智能和计算机视觉领域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;是一种广泛使用的实时目标检测算法。为了直观地展示YOLO算法的检测效果&#xff0c;我们使用Pyqt框架进行检测结果的可视化&#xff0c;同时为了使其能够脱离Python环境&#xff0c;我们…

2.1 阅读错题---02-04年

引言 2002年-2004年英语阅读错题汇总与分析总结。 一、02年阅读 Text 1 题目&#xff1a;21题 题型&#xff1a;细节题 原因&#xff1a;单词认错了&#xff0c;原句中 in sympathy with 译为 与…一致 &#xff1b;题干中的 sympathy 译为 同情 题目&#xff1a;22题 题…

Axure疑难杂症:中继器制作下拉菜单(多级中继器高级交互)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 本文视频课程记录于上述地址第五章中继器专题第11节 课程主题:中继器制作下拉菜单 主要内容:创建条件选区、多级中继器…

即刻启程,踏上W55MH32高性能以太网单片机学习之路!

单芯片解决方案&#xff0c;开启全新体验——W55MH32 高性能以太网单片机 W55MH32是WIZnet重磅推出的高性能以太网单片机&#xff0c;它为用户带来前所未有的集成化体验。这颗芯片将强大的组件集于一身&#xff0c;具体来说&#xff0c;一颗W55MH32内置高性能Arm Cortex-M3核心…

C++负载均衡远程调用学习之上报功能与存储线程池

目录 1. Lars-reportV0.1 report模块介绍 2.Lars-reporterV0.1 reporter项目目录构建 3.Lars-ReporterV0.1 数据表和proto协议环境搭建 4.Lars-ReporterV0.1上报请求业务处理 5.Lars-ReporterV0.1上报请求模块的测试 6.Lars-ReporterV0.2开辟存储线程池-网络存储分离 1. L…

LabVIEW三轴电机控制

在工业自动化迅猛发展的当下&#xff0c;多轴伺服电机控制系统在制造业、3D 打印等众多领域的需求与日俱增。它不仅要实现高精度的单轴运动控制&#xff0c;还需保障多轴协同作业的精准度&#xff0c;对响应速度也有严格要求。LabVIEW 开发多轴伺服电机控制系统&#xff0c;有效…

驱动开发硬核特训 · Day 27(下篇):深入掌握 Common Clock Framework 架构与实战开发

节。 在本篇内容中&#xff0c;我们将围绕 Linux 内核中的时钟子系统核心架构 —— Common Clock Framework&#xff08;简称 CCF&#xff09;展开深入讲解&#xff0c;目标是帮助你全面理解其设计理念、主要数据结构、注册流程、驱动实现方式&#xff0c;以及如何基于 NXP i.M…