【Go】Go語言結構體筆記

整體介紹

雖然 Go 語言不是傳統意義上的面向對象語言,但它提供了結構體(struct)來組織數據,并且可以為結構體綁定方法,從而達到面向對象的部分效果。
關鍵知識點包括:

  • 結構體定義與實例化

    • 定義結構體時使用 type ... struct{} 語法,字段可以是各種數據類型。
    • 實例化結構體可以使用字面量、new 函數或匿名結構體語法。
  • 方法綁定

    • 為結構體綁定方法時可以選擇值接收者或指針接收者。
    • 值接收者方法操作的是副本,指針接收者方法可以修改原始數據。
  • 匿名結構體

    • 無需單獨定義類型,定義時直接實例化。
    • 匿名字段:結構體中直接嵌入字段(類型名作為字段名),簡化代碼。
  • 空結構體

    • 空結構體 struct{} 占用 0 內存,可用于實現方法接收者、作為集合的值(類似只有 key 的字典)或作為信號通道的數據類型。

接下來按照這些知識點整理代碼示例。


1. 結構體的定義與實例化

1.1 定義結構體和使用字面量實例化(指針類型和非指針類型)

代碼示例:

// 文件名: 01_struct_definition.go
package mainimport "fmt"// 定義一個結構體 Student
type Student struct {id     intname   stringage    intschool string
}func main() {// 使用字面量實例化結構體,并取指針(指針類型實例)pan := &Student{id:     1,name:   "luobozi",age:    18,school: "znlsw",}// 使用指針訪問字段(語法糖支持直接 . 操作)fmt.Println("pan.name:", pan.name)// 修改字段pan.age = 20fmt.Printf("pan: %+v\n", pan)// 直接實例化結構體(值類型實例)bo := Student{id:   3,name: "luobozi",age:  18,}fmt.Printf("bo: %+v\n", bo)
}

說明:

  • 使用 &Student{...} 得到結構體指針;直接寫 Student{...} 得到值類型實例。
  • 使用字面量可以直接初始化各個字段。

1.2 使用 new 函數實例化結構體

代碼示例:

// 文件名: 01_struct_new.go
package mainimport "fmt"type Student struct {id   intname stringage  int
}func main() {// 使用 new 函數實例化,返回的是指針類型luo := new(Student)luo.id = 2luo.name = "luobozi"fmt.Printf("luo: %+v\n", luo)
}

說明:

  • new(Student) 分配內存并返回指針,適用于結構體實例化;與字面量方式相比,new 返回的所有字段都是零值。

2. 值類型與指針類型的賦值

代碼示例:

// 文件名: 01_struct_assignment.go
package mainimport "fmt"type Student struct {id   intname stringage  int
}func main() {// 指針類型賦值:兩個指針引用同一對象,修改其中一個會影響另一方luo := new(Student)luo.id = 2luo.name = "luobozi"luo2 := luoluo.id = 999fmt.Println("luo2.id:", luo2.id, "luo.id:", luo.id)// 值類型賦值:會拷貝一份數據,互不影響bo := Student{id:   3,name: "luobozi",age:  18,}bo2 := bobo2.name = "張三"fmt.Println("bo2.name:", bo2.name, "bo.name:", bo.name)
}

說明:

  • 指針賦值只是復制地址,值類型賦值會拷貝整個結構體數據。

3. 方法綁定(值接收者與指針接收者)

代碼示例:

// 文件名: 01_struct_method.go
package mainimport "fmt"type Student struct {id   intname stringage  int
}// 值接收者方法:對副本操作,修改不會反映到原變量
func (s Student) ChangeName(name string) {fmt.Println("調用方法 ChangeName (值接收者)")s.name = name
}// 指針接收者方法:修改原結構體數據
func (s *Student) ChangeName2(name string) {fmt.Println("調用方法 ChangeName2 (指針接收者)")s.name = name
}func main() {bo := Student{id:   3,name: "luobozi",age:  18,}luo := new(Student)luo.id = 2luo.name = "luobozi"// 調用值接收者方法(修改不會影響原變量)bo.ChangeName("milamn")fmt.Println("bo after ChangeName:", bo)// 調用指針接收者方法(原變量被修改)luo.ChangeName("luji")fmt.Println("luo after ChangeName (值方式調用):", luo)luo.ChangeName2("mikod")fmt.Println("luo after ChangeName2:", luo)
}

說明:

  • 使用值接收者時,方法操作的是結構體副本;而指針接收者方法可以直接修改原數據。

4. 匿名結構體

代碼示例:

// 文件名: 01_struct_anonymous.go
package mainimport "fmt"func main() {// 定義并實例化匿名結構體,不需要提前定義類型abc := struct {abcid   intabcaddr string}{abcid:   10,abcaddr: "長沙",}fmt.Println("匿名結構體 abcaddr:", abc.abcaddr)
}

說明:

  • 匿名結構體適用于一次性使用,不需要復用結構體類型的場景。

5. 匿名字段

代碼示例:

// 文件名: 01_struct_anonymousField.go
package mainimport "fmt"// 定義結構體時,直接嵌入類型作為匿名字段
type Person struct {stringint
}func main() {// 匿名字段的賦值按照字段順序進行qwe := Person{"niming", 2,}fmt.Printf("匿名字段 Person: %+v\n", qwe)
}

說明:

  • 匿名字段使得結構體中的字段沒有顯式的名字,訪問時直接用類型名(或通過順序),可以簡化代碼結構。

6. 空結構體及其應用

6.1 空結構體作為方法接收者

代碼示例:

// 文件名: 01_struct_empty.go
package mainimport "fmt"// 定義空結構體 Temp
type Temp struct{}func (t *Temp) Call() {fmt.Println("call for temp")
}func main() {t := &Temp{}t.Call()
}

說明:

  • 空結構體 struct{} 占用內存為 0,經常用作占位符或實現接口的方法接收者。

6.2 空結構體實現集合(Set)

代碼示例:

// 文件名: 01_struct_set.go
package mainimport "fmt"// 定義 Set 類型,其本質上是 map[string]struct{},空結構體不占用內存
type Set map[string]struct{}// 為 Set 添加元素
func (s Set) Append(k string) {s[k] = struct{}{}
}func main() {s := make(Set)s.Append("hello")s.Append("world")// 輸出集合中所有的 keyfor key := range s {fmt.Println("set key:", key)}
}

說明:

  • 使用 map[string]struct{} 實現集合(只關心 key,value 為空結構體),這種方式占用內存極小,非常適合存儲唯一且不可重復的鍵。

總結

本篇筆記涵蓋了 Go 語言中結構體的核心知識點:

  1. 結構體定義與實例化:包括指針與值的實例化方式以及使用 new 和字面量。
  2. 賦值方式:指針賦值(共享同一內存)與值賦值(拷貝數據)。
  3. 方法綁定:值接收者與指針接收者的區別。
  4. 匿名結構體:直接定義并實例化一次性使用。
  5. 匿名字段:在結構體中嵌入類型作為字段。
  6. 空結構體及集合應用:空結構體用于方法接收者、占位或實現集合。

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

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

相關文章

Three.js 快速入門教程【十八】射線拾取模型——鼠標點擊屏幕選中模型或物體

系列文章目錄 Three.js 快速入門教程【一】開啟你的 3D Web 開發之旅 Three.js 快速入門教程【二】透視投影相機 Three.js 快速入門教程【三】渲染器 Three.js 快速入門教程【四】三維坐標系 Three.js 快速入門教程【五】動畫渲染循環 Three.js 快速入門教程【六】相機控件 Or…

Object.defineProperty()Proxy詳解(Vue23數據劫持實現)

底層原理👇🏿 總結一下,結構應該包括: 1. 方法的基本作用和參數。 2. 數據描述符和存取描述符的區別。 3. 屬性定義的內部處理流程。 4. 在Vue中的應用實例。 5. 常見錯誤和正確實踐。 每個部分都要結合搜索結果的信息&…

MySQL 進階語法:函數、約束、多表查詢、事務

目錄 一、MySQL 常用函數 1. 字符串函數 1.1 基本字符串操作 1.2 字符串截取與處理 1.3 字符串搜索與替換 2. 數值函數 2.1 基本數學運算 2.2 數學計算 2.3 隨機數與符號 3. 日期時間函數 3.1 獲取當前時間 3.2 日期時間計算 3.3 日期時間提取 3.4 日期時間格式化…

第 12 章(番外)| Solidity 安全前沿趨勢 × 審計生態 × 職業路徑規劃

🌐 第 12 章(番外)| Solidity 安全前沿趨勢 審計生態 職業路徑規劃 ——做得了審計,也接得了項目,走進 Web3 安全工程師的職業實戰地圖 ? 本章導讀 Solidity 安全,不只是代碼安全、業務安全、審計安全…

1、pytest基本用法

目錄 先給大家分享下學習資源 1. 安裝pytest 2. 編寫用例規則 3. 執行用例 最近在學習pytest的用法 并且用這套框架替換了原來的unittest, 同是測試框架 確實感覺到pytest更加便捷 這邊分享給大家我得學習心得 先給大家分享下學習資源 1 官方文檔 pytest 官方…

【sylar-webserver】5 協程調度模塊

文章目錄 設計思路三種協程的切換 協程調度模塊,需要把前面的線程模塊和協程模塊結合使用 ~ 設計思路 構造函數定義 線程池 基本信息。start(),創建線程池,每個線程創建都執行 run()。每個線程在 run() 里,查找任務隊列 m_tasks…

Go 語言規范學習(1)

文章目錄 IntroductionNotation示例(Go 語言的 if 語句): Source code representationCharacters例子:變量名可以是中文 Letters and digits Lexical elementsCommentsTokensSemicolons例子:查看程序所有的token Ident…

探索抓包利器ProxyPin,實現手機APP請求抓包,支持https請求

以下是ProxyPin的簡單介紹: - ProxyPin是一個開源免費HTTP(S)流量捕獲神器,支持 Windows、Mac、Android、IOS、Linux 全平臺系統- 可以使用它來攔截、檢查并重寫HTTP(S)流量,支持捕獲各種應用的網絡請求。ProxyPin基于Flutter開發&#xff0…

深度學習3-pytorch學習

深度學習3-pytorch學習 Tensor 定義與 PyTorch 操作 1. Tensor 定義: Tensor 是 PyTorch 中的數據結構,類似于 NumPy 數組。可以通過不同方式創建 tensor 對象: import torch# 定義一個 1D Tensor x1 torch.Tensor([3, 4])# 定義一個 Fl…

深入淺出Spring-Boot-3.x.pdf

通過網盤分享的文件:深入淺出Spring-Boot-3.x.pdf 鏈接: https://pan.baidu.com/s/10ZkhmeIXphEwND9Rv4EBlg?pwduatm 提取碼: uatm

springboot啟動事件CommandLineRunner使用

什么是CommandRunner CommandRunner是springboot啟動完成時會調用的一個runner 啟動參數會傳遞到這個runner 我們能用來做一些初始化工作和緩存預熱等工作 ApplicationRunner VS CommandRunner? 這兩個Runner作用一樣 只是得到的啟動參數格式不一樣 前者是一個Argument對象…

數據可視化TensorboardX和tensorBoard安裝及使用

tensorBoard 和TensorboardX 安裝及使用指南 tensorBoard 和 TensorBoardX 是用于可視化機器學習實驗和模型訓練過程的工具。TensorBoard 是 TensorFlow 官方提供的可視化工具,而 TensorBoardX 是其社區驅動的替代品,支持 PyTorch 等其他框架。以下是它…

藍橋杯C++基礎算法-多重背包

這段代碼實現了一個多重背包問題的動態規劃解法。多重背包問題與完全背包問題類似,但每個物品有其數量限制。以下是代碼的詳細思路解析: 1. 問題背景 給定 n 個物品,每個物品有其體積 v[i]、價值 w[i] 和數量 s[i],以及一個容量為…

【SUNO】【AI作詞】【提示詞】

仿寫歌詞提示詞模板(升級版) 一、仿寫目標 風格定位 音樂風格: [填寫目標風格,如:民謠/流行/古風/電子/爵士等]參考案例:如《成都》的敘事民謠,《孤勇者》的勵志流行。 情感基調: […

26考研——樹與二叉樹_樹與二叉樹的應用(5)

408答疑 文章目錄 三、樹與二叉樹的應用哈夫曼樹和哈夫曼編碼哈夫曼樹的定義概念帶權路徑長度(WPL)計算示例分析 哈夫曼樹的構造算法描述哈夫曼樹的性質示例 哈夫曼編碼Huffman樹的編碼規則Huffman樹的構建過程前綴編碼前綴編碼的分析及應用 Huffman樹的…

【VUE】day06 動態組件 插槽 自定義指令 ESlint

【VUE】day06 動態組件 & 插槽 & 自定義指令 1. 動態組件1.1 通過不同的按鈕展示不同的組件1.1.1回顧click 1.2 keep-alive的使用1.3 keep-alive對應的生命周期函數1.3.1 keep-alive的include屬性1.3.2 exclude 1.4 組件注冊名稱和組件聲明時name的區別1.4.1 組件聲明時…

nodejs-原型污染鏈

還是老規矩,邊寫邊學,先分享兩篇文章 深入理解 JavaScript Prototype 污染攻擊 | 離別歌 《JavaScript百煉成仙》 全書知識點整理-CSDN博客 Ctfshow web入門 nodejs篇 web334-web344_web334 ctfshow-CSDN博客 334-js審計 var express require(expr…

Oracle 數據庫通過exp/imp工具遷移指定數據表

項目需求:從prod數據庫遷移和復制2個表(BANK_STATE,HBS)的數據到uat數據庫環境。 數據庫版本:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 遷移工具:客戶端exp/imp工具 -- 執行命令 從Prod數據庫導出數據exp us…

企業級基于SpringBoot的MQTT的構建和使用

基于SpringBoot的MQTT配置及使用 首先要使用EMQX搭建一個MQTT服務器&#xff0c;參考文檔&#xff1a;EMQX快速開始 本著開源分享的觀點&#xff0c;閑話不多說&#xff0c;直接上代碼 導入Maven <dependency><groupId>org.springframework.integration</gro…

26考研——圖_圖的代碼實操(6)

408答疑 文章目錄 五、圖的代碼實操圖的存儲鄰接矩陣結構定義初始化插入頂點獲取頂點位置在頂點 v1 和 v2 之間插入邊獲取第一個鄰接頂點獲取下一個鄰接頂點顯示圖 鄰接表結構定義初始化圖插入頂點獲取頂點位置在頂點 v1 和 v2 之間插入邊獲取第一個鄰接頂點獲取下一個鄰接頂點…