【Go語言圣經3.6】

目標

概念

  1. 常量與變量的主要區別在于:
    • 不可變性:常量在聲明后其值就固定下來,不能再被修改。這保證了程序運行時不會因意外修改而導致錯誤。
      • 使用不可變數據(例如數學常數 π)可以避免意外修改帶來的問題
    • 編譯期計算:常量表達式在編譯期間就會被求值,這不僅減少了運行時的計算負擔,還意味著許多在運行時可能出錯的操作(比如除零、越界)都可以在編譯階段捕獲。
  2. Go 中常量的潛在類型為布爾型、字符串或數字
  3. 無類型常量:在定義時沒有顯式指定類型的常量。比如寫 3.140"hello",這些數值或字符串常量在初始狀態下沒有固定的類型。
  4. 六種無類型常量:分別對應布爾、整數、字符(rune)、浮點數、復數和字符串。
  5. 無類型常量更高精度的運算:無類型常量在算術運算中擁有比具體類型(如 int 或 float64)更高的精度(可以看作有 256 位或更多位的精度);像 ZiB 或 YiB 這樣超出任何內置整數類型范圍的常量,也仍然可以參與運算(例如 YiB / ZiB),因為在編譯期編譯器會將它們按照數學上準確的值處理。

要點

常量聲明

  1. 聲明常量時,可以直接賦予初值:

    
    const pi = 3.14159 // 近似值;實際上 math.Pi 提供了更精確的值
    

    這和變量聲明語法類似,但常量的值一旦設定就不能修改。

  2. 批量聲明常量

    多個相關常量可以使用小括號一起聲明:

    const (e  = 2.71828182845904523536028747135266249775724709369995957496696763pi = 3.14159265358979323846264338327950288419716939937510582097494459
    )

    這樣的批量聲明不僅代碼更簡潔,也可以利用類型推斷:如果沒有顯式指定類型,常量的類型會根據右側的表達式自動推斷。

    類型推斷說明

    • 如果你在常量聲明時沒有顯式標明類型,則 Go 會根據右邊的表達式推斷類型。例如:

      const timeout = 5 * time.Minute
      

      此時 timeout 會被推斷為 time.Duration 類型,因為 time.Minute 本身是 time.Duration 類型的常量。

編譯期常量表達式與優化

在數組定義中,可以用常量來指定數組的長度:

const IPv4Len = 4func parseIPv4(s string) IP {var p [IPv4Len]byte// 解析 IPv4 地址的邏輯
}

這樣,數組長度在編譯期間就確定下來了。程序運行時減少了不必要的計算,提高了效率。

iota常量生成器

  1. iota的基本原理

    • 自動遞增:在一個 const 聲明塊中,iota 是一個預定義標識符,它在第一行被置為 0,后續每出現一行常量聲明,它的值自動加 1。
    • 省略初始化表達式:如果在常量聲明塊中,后面的常量省略了右側的表達式,那么它們將默認使用前一行的表達式。這樣在簡單的復制中,雖然沒有太大實用價值,但在配合 iota 時可以生成有規律的值。
  2. 例子

    type Weekday intconst (Sunday Weekday = iota  // 0Monday                 // 1Tuesday                // 2Wednesday              // 3Thursday               // 4Friday                 // 5Saturday               // 6
    )

    這種方式使得常量的賦值變得簡單且易于維護。

  3. iota 還常用于生成一系列位掩碼(bit mask)

    type Flags uintconst (FlagUp Flags = 1 << iota      // 1 << 0 = 1 (第 0 位)FlagBroadcast                 // 1 << 1 = 2 (第 1 位)FlagLoopback                  // 1 << 2 = 4 (第 2 位)FlagPointToPoint              // 1 << 3 = 8 (第 3 位)FlagMulticast                 // 1 << 4 = 16 (第 4 位)
    )

    每個常量都代表一個單獨的 bit 位,這樣在設置或測試標志時,可以使用位運算:

    • 測試標志v & FlagUp == FlagUp
    • 清除標志v &^= FlagUp —— 把 v 中與 FlagUp 對應的那一位變成 0(不管原來是1還是0)。這樣就清除了這個標志。
    • 設置標志v |= FlagBroadcast —— 把 v 中與 FlagBroadcast 對應的那一位變成1(即使之前是0)
  4. 利用 iota 生成一系列以 1024 為底的冪(例如 KiB、MiB 等)

    const (_ = 1 << (10 * iota)KiB // 1 << 10 = 1024MiB // 1 << 20 = 1048576GiB // 1 << 30 = 1073741824TiB // 1 << 40 = 1099511627776PiB // 1 << 50 = 1125899906842624EiB // 1 << 60 = 1152921504606846976// ZiB, YiB 等可能會超過某些平臺的位數限制
    )

    通過這種方式,編譯器自動計算出每一項的值,而無需手動寫出復雜的計算。

  5. 局限性

    不能產生任意的冪:例如,要生成 1000、1000000 等(通常用于 KB、MB 等),因為 Go 語言沒有內置的冪運算符(如 **pow),所以不能直接利用 iota 來生成 10 的冪。

無類型常量的靈活性:隱式轉換

當你將無類型常量賦值給一個變量時,Go 編譯器會根據上下文自動推斷出一個“默認類型”。例如:

  • var x float64 = math.Pi
    這里,math.Pi 是一個無類型浮點常量,賦值時自動轉換成 float64。

  • 又如:

    
    i := 0      // 隱式為 int 類型
    f := 0.0    // 隱式為 float64 類型
    c := 0i     // 隱式為 complex128 類型
    r := '\000'// 隱式為 rune(int32)類型

    對于一個沒有顯式類型的變量聲明(包括簡短變量聲明),常量的形式將隱式決定變量的默認類型,

這種機制讓我們在書寫表達式時更靈活,無需反復寫類型轉換代碼。

隱式轉換與默認類型

當無類型常量出現在需要具體類型的上下文時(比如當一個無類型的常量被賦值給一個變量的時候),編譯器會自動進行轉換。例如:

var f float64 = 3 + 0i // 這里 3+0i 是無類型復數,但可以隱式轉換為 float64

這種轉換類似于在后臺寫了:

var f float64 = float64(3 + 0i)

注意: 轉換要求目標類型必須能表示原始常量的值。如果值太大或不適合,則會導致編譯錯誤。例如:

  • 將一個超出 int32 范圍的無類型整數轉換為 int32,會報錯;
  • 將一個超出 float64 表示范圍的浮點數轉換為 float64,同樣會報錯。

無類型常量隱式轉換的更多例子

var f float64 = 212
fmt.Println((f - 32) * 5 / 9)     // 輸出 "100"
fmt.Println(5 / 9 * (f - 32))       // 輸出 "0"
fmt.Println(5.0 / 9.0 * (f - 32))   // 輸出 "100"
  • 第一行(f - 32) 是 float64,乘以 5 后依然是 float64,然后除以 9,所有運算都是浮點運算,所以結果正確(100)。
  • 第二行5 / 9 兩個都是無類型整數(隱式為 int),整數除法結果為 0(因為 5/9 小于 1,用整數運算取整),導致整個表達式結果為 0。
  • 第三行5.09.0 是無類型浮點常量,所以 5.0/9.0 得到正確的浮點值,再乘以 (f - 32) 得到 100。

關鍵點:常量的寫法決定了它們在運算中的默認類型,從而影響最終結果。這也說明了在使用無類型常量時,要注意數值字面量的形式(整數形式或浮點形式)對運算結果的影響。

fmt.Println(YiB / ZiB) // 輸出 "1024"
  • 即便 ZiB 和 YiB 的值超出了 Go 內置整數類型能表達的范圍,它們仍然可以參與運算.

類型與接口轉換

當無類型常量賦值給接口變量時,接口的動態類型取決于常量的默認類型

fmt.Printf("%T\n", 0)      // 輸出 "int"
fmt.Printf("%T\n", 0.0)    // 輸出 "float64"
fmt.Printf("%T\n", 0i)     // 輸出 "complex128"
fmt.Printf("%T\n", '\000') // 輸出 "int32"(也稱為 rune)

這對接口編程非常關鍵,因為接口在運行時需要知道底層數據的具體類型。

語言特性

練習

  1. 編寫KB、MB的常量聲明,然后擴展到YB。

    const (KB = 1000MB = 1000 * KBGB = 1000 * MBTB = 1000 * GBPB = 1000 * TBEB = 1000 * PBZB = 1000 * EBYB = 1000 * ZB
    )

總結

  1. iota 常量生成器:iota 是一個強大的工具,可以方便地生成有規律的數值序列,適用于枚舉、位標志、以及其他有序數值集合的定義。
  2. 有一類常量稱為“無類型常量”,這類常量在聲明時不被賦予一個具體的基礎類型,而是保持一種更“通用”的狀態。這樣做有兩個好處:
    • 更高精度的運算:無類型常量在算術運算中擁有比具體類型(如 int 或 float64)更高的精度(可以看作有 256 位或更多位的精度)。
    • 靈活的隱式轉換:當無類型常量賦值給變量時,編譯器會自動將它們轉換成變量所需要的類型(如果轉換合法),這樣可以直接用于多種場合,減少顯式轉換的麻煩。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73806.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73806.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73806.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于x11vnc的ubuntu遠程桌面

1、安裝VNC服務 sudo apt install x11vnc -y2、創建連接密碼 sudo x11vnc -storepasswd3、安裝lightdm服務 x11vnc 在 默認的 GDM3 中不起作用&#xff0c;因此需要使用 lightdm 桌面管理環境 sudo apt install lightdm -y切換至lightdm&#xff0c;上一步已經切換則跳過該…

leetcode日記(105)買賣股票的最佳時機Ⅱ

原本以為是一個很難想的動態規劃&#xff0c;沒想到是最簡單的貪心…… 如果實在想不出就畫個折線圖&#xff0c;只買上漲的就行了&#xff0c;所有上漲的段都取到。 真的沒想到會這么簡單…… class Solution { public:int maxProfit(vector<int>& prices) {int …

手寫發布訂閱模式

手寫實現一個簡易的發布訂閱模式&#xff0c;通常有以下幾個關鍵點&#xff1a; 訂閱&#xff08;subscribe&#xff09;&#xff1a;用戶訂閱特定的事件&#xff0c;當該事件觸發時&#xff0c;執行與事件關聯的回調函數。 發布&#xff08;publish&#xff09;&#xff1a;當…

docker入門篇

使用docker可以很快部署相同的環境,這也是最快的環境構建,接下來就主要對docker中的基礎內容進行講解.Docker 是一個用于開發、交付和運行應用程序的開源平臺&#xff0c;它可以讓開發者將應用程序及其依賴打包到一個容器中&#xff0c;然后在任何環境中運行這個容器&#xff0…

Qt Widgets、Qt Quick

一、核心概念 ?Qt Widgets? Qt框架中的傳統桌面UI開發組件庫&#xff0c;基于C實現&#xff0c;提供按鈕、文本框等控件?。適用于需要深度集成操作系統底層功能或復雜業務邏輯的桌面應用?。 ?Qt Quick? QML的標準庫和工具包&#xff0c;提供預置的視覺組件&#xff08;如…

LinuX---Shell正則表達式

正則表達式 正則表達式使用單個字符串來描述、匹配一系列符合某個語法規則的字符串。在很多文本編輯器里&#xff0c;正則表達式通常被用來檢索、替換那些符合某個模式的文本。在Linux中&#xff0c;grep&#xff0c;sed&#xff0c;awk等命令都支持通過正則表達式進行模式匹配…

nginx配置txt文件點擊鏈接后下載

手上有一個txt文件&#xff0c;上傳到文件服務器后&#xff0c;點擊路徑是在瀏覽器里直接打開了&#xff0c;用戶需要的是下載到本地 nginx新增配置 location ~* /ExcelDownload/envScript/(.\.txt) {add_header Content-Disposition "attachment; filename$1";add…

相機光學(四十七)——相紙材質

1. 光面相紙 光面相紙表面光滑&#xff0c;亮度高&#xff0c;反光性好&#xff0c;能夠呈現出清晰、鮮艷的圖像效果&#xff0c;適合用于表現色彩艷麗、反差要求較高的題材&#xff0c;如產品照、藝術照和風景照。然而&#xff0c;這種相紙容易沾上指紋和灰塵。 2. 絨面相紙…

LabVIEW 線性擬合

該 LabVIEW 程序實現了 線性擬合&#xff08;Linear Fit&#xff09;&#xff0c;用于計算給定一組數據點的斜率&#xff08;Slope&#xff09;和截距&#xff08;Intercept&#xff09;&#xff0c;并將結果可視化于 XY Graph 中。本案例適用于數據擬合、實驗數據分析、傳感器…

Swift 并發中的任務讓步(Yielding)和防抖(Debouncing)

網羅開發 &#xff08;小紅書、快手、視頻號同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企業從事人工智能項目研發管理工作&#xff0c;平時熱衷于分享各種編程領域的軟硬技能知識以及前沿技術&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

【Android】RuntimeShader 應用

1 簡介 RuntimeShader 是 Android 13&#xff08;T&#xff09;中新增的特性&#xff0c;用于逐像素渲染界面&#xff0c;它使用 AGSL&#xff08;Android Graphics Shading Language&#xff09;編寫著色器代碼&#xff0c;底層基于 Skia 圖形渲染引擎。官方介紹詳見 → Runti…

小程序API —— 53 本地存儲

小程序本地存儲是指在小程序中使用 API 將數據存儲在用戶的設備上&#xff0c;以便小程序在運行時和下次啟動時快速地讀取這些數據&#xff1b; 小程序本地存儲的 API 可以分為兩類&#xff0c;每一類可以分為四種&#xff1a; 同步 API&#xff1a; 存儲&#xff1a;wx.setS…

el-table樹形表格合并相同的值

el-table樹形表格合并相同的值 el-table樹形表格合并相同的值讓Ai進行優化后的代碼 el-table樹形表格合并相同的值 <style lang"scss" scoped> .tableBox {/deep/ &.el-table th:first-child,/deep/ &.el-table td:first-child {padding-left: 0;} } …

虛幻基礎:移動組件

文章目錄 移動組件&#xff1a;角色的移動信息和移動控制walk&#xff1a;行走falling&#xff1a;跳躍&下落 通用設置重力&#xff1a;模式通用重力max acceleration&#xff1a;模式通用加速度 walk制動降速行走&#xff1a;速度超過最大速度時的減速力 falling空氣控制空…

DeepSeek + Kimi 自動生成 PPT

可以先用deepseek生成ppt大綱&#xff0c;再把這個大綱復制到Kimi的ppt助手里&#xff1a; https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 選擇ppt模板&#xff1a; 點擊生成ppt就制作好了。

Unity 解決TMP_Text 文字顯示異常的問題

問題 Unity 中TMP_Text 文字顯示異常大多可分為兩種情況。①制作TMP 字體選用的文本不包含該文字&#xff1b;②制作TMP 字體選用的ttf 源不包含該文字。 第一種情況&#xff0c;制作TMP 字體選用的文本不包含&#xff0c;只需在選用的Charater File 中添加再重新生成即可。 …

Day19:把數字翻譯成字符串

現有一串神秘的密文 ciphertext&#xff0c;經調查&#xff0c;密文的特點和規則如下&#xff1a; 密文由非負整數組成數字 0-25 分別對應字母 a-z 請根據上述規則將密文 ciphertext 解密為字母&#xff0c;并返回共有多少種解密結果。 LCR 165. 解密數字 - 力扣&#xff08…

CentOS下安裝ElasticSearch(日志分析)

準備目錄 搞一個自己喜歡的目錄 mkdir /usr/local/app 切換到該目錄 cd /usr/local/app 下載 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.9.2-linux-x86_64.tar.gz 選擇其他版本 點擊進入官網

汽車機械鑰匙升級一鍵啟動的優點

汽車機械鑰匙升級一鍵啟動的優點主要包括&#xff1a; 便捷性&#xff1a;一鍵啟動功能的引入極大地提升了用車便捷性。車主無需翻找鑰匙&#xff0c;只需在車輛感應范圍內輕觸啟動鍵&#xff0c;即可輕松發動汽車。 安全性&#xff1a;移動管家專車專用一鍵啟動系統配備了防…

【深度學習量化交易16】觸發機制設置——基于miniQMT的量化交易回測系統開發實記

我是Mr.看海&#xff0c;我在嘗試用信號處理的知識積累和思考方式做量化交易&#xff0c;應用深度學習和AI實現股票自動交易&#xff0c;目的是實現財務自由~ 目前我正在開發基于miniQMT的量化交易系統——看海量化交易系統。 很多朋友關心回測系統的開發進展&#xff0c;在正式…