Go類型全解:常量與變數大全!

来源:https://www.cnblogs.com/xfuture/archive/2023/09/09/17690091.html
-Advertisement-
Play Games

本篇文章深入探討了 Go 語言中類型確定值、類型不確定值以及對應類型轉換的知識點,後續充分解析了常量與變數及其高級用法,並舉出豐富的案例。 關註公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩, ...


本篇文章深入探討了 Go 語言中類型確定值、類型不確定值以及對應類型轉換的知識點,後續充分解析了常量與變數及其高級用法,並舉出豐富的案例。

關註公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

file

一、類型確定值

類型確定值是與特定數據類型明確綁定的。類型確定值在 Go 中占有很大一部分領域,包括但不限於常量、變數、函數返回值、結構體欄位等。下麵是對類型確定值的的示例:

類型確定值在變數聲明中

當你在變數聲明中明確指定了類型,那麼這個變數就是類型確定值。

var x int = 10 // x 是類型確定值,類型為 int
var y string = "Hello" // y 是類型確定值,類型為 string

類型確定值在函數返回值中

函數也可以返回類型確定值。

func sum(a int, b int) int { // 返回值類型明確為 int
    return a + b
}

類型確定值在結構體欄位中

結構體欄位也是類型確定值。

type Person struct {
    Name string // Name 是類型確定值,類型為 string
    Age  int    // Age 是類型確定值,類型為 int
}

類型確定值在數組和切片中

數組和切片的元素也是類型確定值。

var arr [3]int = [3]int{1, 2, 3} // arr 是類型確定值,類型為 [3]int
var s []string = []string{"a", "b", "c"} // s 是類型確定值,類型為 []string

類型確定值在介面和類型斷言中

當你通過類型斷言將介面值轉換為某個具體類型時,結果是類型確定值。

var i interface{} = "this is string"
str, ok := i.(string) // str 是類型確定值,類型為 string

類型確定值在類型別名和自定義類型中

即使你創建了一個類型別名或自定義類型,實際上還是與原始類型綁定的類型確定值。

type Length int
var l Length = 10 // l 是類型確定值,類型為 Length

這些例子展示了類型確定值如何滲透到 Go 語言的各個方面,為開發者提供了嚴格的類型安全性。在編寫代碼時,對類型有明確的瞭解可以幫助你編寫更健壯、更安全的程式。


二、類型不確定值

類型不確定值是沒有明確類型的值。這些值不是與任何具體的數據類型綁定的,因此在編譯時,Go 編譯器會根據上下文來推斷其類型。在 Go 中,類型不確定值是一個相當有趣和多面性的概念。這些值存在於常量聲明、算術運算、以及一些內建函數中。下麵是對類型不確定值的的示例:

在算術運算中的類型不確定值

當你使用類型不確定值進行算術運算時,結果也是類型不確定值,除非運算中有一個類型確定值,這種情況下,結果將是類型確定值。

const c = 3  // 類型不確定值
var d int = 2  // 類型確定值

// e 依然是類型不確定值,因為參與運算的兩個值都是類型不確定值
const e = c * c 

// f 是類型確定值,因為參與運算的有一個類型確定值
var f = c * d 

在內建函數中的類型不確定值

一些 Go 的內建函數(如 len)返回類型不確定值。

const s = "hello world"
const l = len(s)  // l 是類型不確定值

類型不確定值與預設類型

每個類型不確定值都有一個與之關聯的預設類型,通常是基於字面量或者運算表達式。

const g = 42.0  // 預設類型是 float64
const h = 'x'   // 預設類型是 rune

類型不確定值在數組長度聲明中

在數組長度聲明中也可使用類型不確定值。

const size = 4
var arr [size]int  // 編譯器推斷 size 為 int

類型不確定值與 iota

iota 也是類型不確定值,經常用於枚舉。

const (
    zero = iota  // zero 是 0
    one         // one 是 1
)

三、顯式類型轉換與類型推斷

在 Go 語言中,類型轉換和類型推斷是兩個相當重要的概念。它們共同定義瞭如何在編譯和運行時處理不同類型的值。我們將詳細討論這兩個概念,並通過示例來闡明其用法和重要性。

顯式類型轉換

顯式類型轉換是通過語法明確地將一個數據類型轉換為另一個數據類型的操作。

定義

在 Go 中,顯式類型轉換的語法是 T(v),其中 T 是目標類型,而 v 是要轉換的值。

var x float64 = 42.0
var y int = int(x)  // 顯式地將 float64 轉換為 int

限制與約束

顯式類型轉換並不總是有效的。轉換的合法性取決於源類型和目標類型。例如,不能直接將一個結構體類型轉換為整數或者浮點數。

type myStruct struct {
    field int
}

var a myStruct
// var b int = int(a)  // 這是不合法的

類型推斷

類型推斷是編譯器自動推斷變數類型的過程。在 Go 中,這通常發生在使用 := 進行變數初始化時。

定義

當使用 := 操作符聲明變數但沒有明確指定類型時,Go 編譯器會根據右側表達式的類型來推斷變數的類型。

z := 42  // 類型被推斷為 int

在複雜表達式中的類型推斷

在涉及多種類型的複雜表達式中,Go 會儘量進行類型推斷以滿足表達式的類型需要。

var m float64 = 3.14
n := int(m) + 42  // int(m) 顯式轉換,結果類型推斷為 int

類型推斷與類型不確定值

類型推斷也適用於類型不確定值。編譯器會根據上下文來推斷其最合適的類型。

const p = 5  // 類型不確定值
var q = p    // 類型推斷為 int,因為 p 的預設類型是 int

四、常量

在 Go 語言中,常量(Constant)是不可改變的值,這一點與變數有明顯區別。一旦一個常量被定義,它的值就不能再被改變。常量可以是類型不確定值或類型確定值。

類型不確定常量

類型不確定常量是沒有明確類型的常量。這些常量不是與任何具體的數據類型綁定的,因此在編譯時,Go 編譯器會根據上下文來推斷其類型。

const a = 42  // a 是類型不確定值,因為沒有明確指定類型

類型確定常量

類型確定常量是與特定數據類型明確綁定的常量。

const c int = 42  // c 是類型確定值,因為其類型明確為 int

常量聲明中的自動補全

在常量聲明塊中,你可以省略後續常量的類型和值,它們會自動補全。

const (
    x int = 10
    y      // y 也是 int 類型,值為 10
)

使用 iota 在常量聲明中

iota 是一個特殊的常量生成器,主要用於創建一組遞增的整數常量。

const (
    zero = iota  // zero 的值為 0
    one          // one 的值為 1
    two          // two 的值為 2
)

常量的可見性和可定址性

常量可以是導出或非導出的,取決於它的名稱是否以大寫字母開頭。常量不是可定址的。

const ExportedConst = "I am visible" // 可導出的常量
const unExportedConst = "I am not visible" // 不可導出的常量

常量溢出和預設類型

一個類型不確定常量所表示的值可能會溢出其預設類型。在這種情況下,只有當這個常量被用於一個可以容納該值的上下文時,編譯才會成功。

const big = 1 << 100 // 預設類型為 int,但值會溢出
var bigInt = big >> 99 // big 被用於一個 int64 上下文,沒有溢出

字元串常量

字元串常量是包含在雙引號中的一系列字元。

const hello = "Hello, world!"

布爾常量

布爾常量只有兩個可能的值:truefalse

const flagTrue = true
const flagFalse = false

枚舉常量

通過使用 iota,你可以創建一組遞增的整數常量,通常用於枚舉。

type Weekday int

const (
    Sunday Weekday = iota
    Monday
    Tuesday
    // ...
    Saturday
)

複數常量

Go 支持複數類型,並且你可以創建複數常量。

const complexConst = 1 + 2i

強制類型轉換

你可以通過強制類型轉換將一個常量轉換為另一種類型。

const integer = 42
const floatType = float32(integer)

計算表達式中的常量

常量也可以是計算表達式的結果,但表達式必須只包含常量值。

const calculated = 3 * 2  // 6

常量數組和切片

需要註意的是,在 Go 中,數組大小需要是常量。但切片和映射的大小可以動態改變,因此它們不能是常量。

const arraySize = 5
var arr [arraySize]int  // 合法

五、變數

變數是存儲數據值的存儲單元,其值可以在運行時改變。在 Go 語言中,變數的使用非常靈活但又具有嚴格的類型安全性。

變數聲明和賦值

基本聲明

使用 var 關鍵字進行變數聲明。

var x int

同時聲明和賦值

var y int = 42

或者使用短變數聲明形式:

z := 42

多變數聲明

var a, b, c int

或者

var (
    d int
    e float64
)

類型描述

基本類型

包括 int, float64, bool, string 等。

var integerVar int = 10
var floatVar float64 = 10.99
var boolVar bool = true
var stringVar string = "Hello, Go"

數值類型

Go 支持多種數值類型,包括 int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64 等。

var smallInt int8 = 127
var largeInt int64 = 9223372036854775807
var unsignedInt uint16 = 65535
var floatNum float32 = 3.141592

字元和字元串

Go 有 runebyte 類型來表示 Unicode 字元和 ASCII 字元。

var asciiChar byte = 'A'
var unicodeChar rune = '你'
var str string = "Hello, World!"

布爾類型

布爾類型只有兩個值:truefalse

var isActive bool = true
var isCompleted bool = false

指針

Go 支持指針類型,但不支持指針運算。

var pointer *int
x := 42
pointer = &x

數組和切片

var arrayExample [5]int = [5]int{1, 2, 3, 4, 5}
var sliceExample []int = arrayExample[1:4]

映射(Maps)

var countryCapitalMap map[string]string
countryCapitalMap = make(map[string]string)
countryCapitalMap["France"] = "Paris"

結構體(Structs)

type Employee struct {
    ID     int
    Name   string
    Salary float64
}

var emp Employee

介面(Interfaces)

type Shape interface {
    Area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return 3.14159 * c.Radius * c.Radius
}

var s Shape = Circle{5.0}

函數類型

Go 中,函數也是一種類型,可以作為參數傳遞。

type AddFunc func(a int, b int) int

var add AddFunc = func(a int, b int) int {
    return a + b
}

通道(Channels)

var messageChannel chan string = make(chan string)

複合類型

例如數組、切片、映射、通道、結構體和介面。

數組

var arr [5]int

切片

var slice []int

映射

var mapping map[string]int

通道

var ch chan int

結構體

type Person struct {
    name string
    age int
}

var p Person

介面

type Geometry interface {
    Area() float64
}

var g Geometry

值的可定址性

Go 語言中有些變數是可定址的,意味著你可以獲取這個變數的記憶體地址。

var myVar int = 42
var p *int = &myVar

變數作用域

在 Go 中,變數可以有不同的作用域:全局作用域、包內作用域、函數作用域、代碼塊作用域等。

var globalVar int  // 全局作用域

func myFunction() {
    var functionVar int  // 函數作用域
    {
        var blockVar int  // 代碼塊作用域
    }
}

七、常量和變數的高級用法

在 Go 編程中,常量和變數不僅僅是數據存儲的簡單方式。它們有各種高級用法,可以用來優化代碼、提高效率或實現複雜的編程模式。

常量的高級用法

枚舉和 iota

Go 通過 iota 關鍵字支持枚舉類型的實現。這在一組常量聲明中是非常有用的。

const (
    Monday = iota + 1  // Monday = 1
    Tuesday            // Tuesday = 2
    Wednesday          // Wednesday = 3
)

類型別名

使用類型別名,你可以將常量限製為自定義類型。

type Weekday int

const (
    Sunday Weekday = iota
    Monday
    // ...
)

無類型和有類型常量

無類型的常量可以用在多種場合,它們會根據上下文進行類型推斷。

const x = 42  // 無類型常量
var i int = x
var f float64 = x

變數的高級用法

變數的作用域

Go 支持塊級作用域。通過 var 關鍵字在不同級別(全局、包級別、函數級別等)聲明變數,你可以控制變數的可見性。

var globalVar = 42  // 全局變數

func main() {
    var funcVar = "I'm local"  // 函數級別變數
}

延遲初始化

使用 init() 函數,你可以在程式開始執行前初始化變數。

var complexVar complex128

func init() {
    complexVar = cmplx.Sqrt(-5 + 12i)
}

指針和地址操作符

雖然 Go 語言沒有提供指針運算,但它允許你通過地址操作符 & 和解引用操作符 * 來操作指針。

x := 42
p := &x
fmt.Println(*p)  // 輸出 42

使用標簽(Tags)和結構體

在結構體中,你可以使用標簽(tags)來附加元數據,這在序列化和反序列化時非常有用。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

file

關註公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

file

如有幫助,請多關註
個人微信公眾號:【TechLeadCloud】分享AI與雲服務研發的全維度知識,談談我作為TechLead對技術的獨特洞察。
TeahLead KrisChang,10+年的互聯網和人工智慧從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿裡雲認證雲服務資深架構師,上億營收AI產品業務負責人。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、前期工作 下載CentOS7鏡像:CentOS-7-x86_64-DVD-2009.iso 安裝虛擬機工具:VirtualBox 2、新建虛擬機 2.1、設置新建虛擬機的名稱、安裝路徑、類型及版本 註意:CentOS Linux 的發行版本是通過編譯 Red Hat, Inc 公開提供的 Red ...
  • 防火牆配置 # 啟動防火牆服務 systemctl start firewalld # 關閉防火牆服務 systemctl stop firewalld # 查看防火牆服務狀態 systemctl status firewalld # 開機禁用防火牆服務 systemctl disable fire ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 一. keep-alive 的作用 二. keep-alive 的原理 三. keep-alive 的應用 四. keep-alive 的刷新 五. keep-alive 頁面緩存思路 一. keep-alive 的作用 首先引用官 ...
  • 前段時間和朋友做了一個區域網考試系統,總共有3個端:考生端、監考端、管理端。 框架與相關的庫 先簡單說明一下我使用的框架和相關的庫: 構建工具:Vite 框架:Vue3 UI組件庫:element-plus 網路請求庫:axios 路由跳轉:vue-router 狀態管理:pinia CSS擴展語言 ...
  • >我們是[袋鼠雲數棧 UED 團隊](http://ued.dtstack.cn/),致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 >本文作者:琉易 [liuxianyu.cn](https://link.juejin.cn/?target=ht ...
  • 以下是一個Python實現的簡單二分查找演算法的代碼示例: def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 # 找到中間元素的索引 ...
  • 一條爬蟲抓取一個小網站所有數據 ​ 今天閑來無事,寫一個爬蟲來玩玩。在網上衝浪的時候發現了一個搞笑的段子網,發現裡面的內容還是比較有意思的,於是心血來潮,就想著能不能寫一個Python程式,抓取幾條數據下來看看,一不小心就把這個網站的所有數據都拿到了。 ​ 這個網站主要的數據都是詳情在HTML裡面的 ...
  • 上篇文章12分鐘從Executor自頂向下徹底搞懂線程池中我們聊到線程池,而線程池中包含阻塞隊列 這篇文章我們主要聊聊併發包下的阻塞隊列 阻塞隊列 什麼是隊列? 隊列的實現可以是數組、也可以是鏈表,可以實現先進先出的順序隊列,也可以實現先進後出的棧隊列 那什麼是阻塞隊列? 在經典的生產者/消費者模型 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...