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
英文地址,請注明出處:http://en.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…