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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...