Go語言基礎之結構體(春日篇)

2020-11-23 51CTO

前言

Hey,大家好呀,我是星期八,終於迎來了Go中最大一個知識點,結構體。

在Go,是沒有類和對象這個概念的。

是通過結構體的各種操作,模擬出來的像Java,Python之類的面向對象的。

回憶map

之前我們講過,Go語言的map是鍵值對的方式存儲數據的,就像這樣的。不記得的小夥伴請戳:一篇文章帶你了解Go語言基礎之map、Go語言基礎之map補充。

  1. //方式一 
  2. var student = map[string]string{ 
  3.     "Name""張三", 
  4.     "Age":  "18", 
  5. //方式二 
  6. var student2 = make(map[string]string, 10) 
  7. student2["Name"] = "張三" 
  8. student2["Age"] = "18" 

但是這樣,似乎有一個弊端,我不知道我有幾個key,並且value類型是固定的。

理論來說,key Age 對應的value應該是int類型,還有一些其他微妙的問題,通過map都是不太好解決的。

因為解決這些問題,所以,又引出了結構體這個類型。

前戲補充

在開始結構體之前呢,先看兩個奇怪的知識點。

自定義類型

  1. type 自定義類型名 類型名 
  2. 例: 
  3. type NewInt int 

完整代碼

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type NewInt int 
  6.  
  7. func main() { 
  8.     var n1 NewInt = 1 
  9.     fmt.Println(n1)//結果為1 

如果要是理解的話,可以理解為NewInt包含了int的功能。

這裡可以把NewInt當作int來使用。

注:NewInt是一個新的類型,它包含int,並不等於int。

類型別名

代碼

  1. type 類型別名 = 類型名 
  2. 例: 
  3. type Nint = int 

完整代碼

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type Nint = int 
  6.  
  7. func main() { 
  8.     var n1 Nint = 1 
  9.     fmt.Println(n1)//1 

自定義類型和類型別名區別

可能猛一看,感覺自定義類型和類型別名似乎一樣,但是其實是不太一樣的。

代碼

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type Nint1 int   //自定義類型 
  6. type Nint2 = int //類型別名 
  7.  
  8. func main() { 
  9.     var n1 Nint1 = 1 
  10.     var n2 Nint2 = 1 
  11.     fmt.Printf("n1類型:%T,n2類型:%T", n1, n2) 

執行結果。

結論:自定義類型真的是自定義類型,類型都變了,類型別名只是類型名變了,但是本質沒變。

結構體

Go語言的結構體,相當Java,Python等語言中的類,已經不再是簡簡單單的結構體那麼簡單了。

結構體屬於基本數據類型。

內存圖大概如下。

結構體定義

定義結構體需要用到關鍵字type和struct。

語法

  1. type 結構體名 struct { 
  2.     欄位1 欄位類型1 
  3.     欄位2 欄位類型2 
  4.     ... 

示例,通過結構體描述一個學生。

  1. type Student struct { 
  2.     Name   string 
  3.     Age    int 
  4.     Height int 
  5.     Weight int 
  6.     phone string 

注:如果欄位類型是相同的,可以寫在同一行。

  1. type Student struct { 
  2.   Name                string 
  3.   Age, Height, Weight int 
  4.   phone               string 

結構體初始化

方式一,賦值時初始化

  1. func main() { 
  2.   var s1 = Student{ 
  3.     Name:   "張三", 
  4.     Age:    18, 
  5.     Height: 180, 
  6.     Weight: 120, 
  7.     phone:  "6666666", 
  8.   } 
  9.   fmt.Println(s1) 

方式二,先聲明,後賦值

  1. func main() { 
  2.   var s1 Student 
  3.   s1.Name = "張三" 
  4.   s1.Age = 18 
  5.   s1.Height = 180 
  6.   s1.Weight = 120 
  7.   s1.phone = "66666" 

兩個執行結果。

匿名結構體

有時候我們的函數可能會要求傳入一個結構體,但是你又不想定義,就想臨時用一下,趕緊傳參得了。

這時候可以考慮匿名結構體。

方式一,先聲明,後賦值

  1. func main() { 
  2.   var car struct { 
  3.     Name   string; 
  4.     CarNum string 
  5.   } 
  6.   car.Name = "QQ" 
  7.   car.CarNum = "京6666" 
  8.   fmt.Println(car) //{QQ 京6666} 

方式二,聲明+初始化

  1. func main() { 
  2.   var car = struct { 
  3.     Name   string; 
  4.     CarNum string 
  5.   }{ 
  6.     Name:   "QQ", 
  7.     CarNum: "京6666", 
  8.   } 
  9.  
  10.   fmt.Println(car) //{QQ 京6666} 

兩個執行結果。

通過&方式初始化結構體

通過&的方式初始化,性能會提高一點,因為返回的是第一個的指針。

但是操作過程跟上述一樣,Go已經封裝好了。

代碼

  1. func main() { 
  2.   //方式一,等於一個空&結構體在賦值 
  3.   var s1 = &Student{} 
  4.   s1.Name = "張三" 
  5.   //... 
  6.   //方式二,直接賦值 
  7.   var s2 = &Student{ 
  8.     Name:   "", 
  9.     Age:    0, 
  10.     Height: 0, 
  11.     Weight: 0, 
  12.     phone:  "", 
  13.   } 
  14.   //方式三不可以 
  15.   //var s3 &Student//error 

使用&的方式基本跟原來一樣,但是方式三不行。

&初始化結構體函數注意事項

如果使用&的方式,那函數參數也要變一下的。

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. type Student struct { 
  6.   Name                string 
  7.   Age, Height, Weight int 
  8.   phone               string 
  9.  
  10. func sayStudent1(s Student) { 
  11.   fmt.Println(s) 
  12. func sayStudent2(s *Student) { 
  13.   //如果穿的是結構體地址,那麼接收就需要用* 
  14.   fmt.Println(s) 
  15. func main() { 
  16.   var s1 = Student{ 
  17.     Name:   "111", 
  18.     Age:    0, 
  19.     Height: 0, 
  20.     Weight: 0, 
  21.     phone:  "1111", 
  22.   } 
  23.   var s2 = &Student{ 
  24.     Name:   "2222", 
  25.     Age:    0, 
  26.     Height: 0, 
  27.     Weight: 0, 
  28.     phone:  "2222", 
  29.   } 
  30.   sayStudent1(s1) 
  31.   sayStudent2(s2) 

執行結果。

關於結構體默認值

代碼

  1. func main() { 
  2.   var s1 = Student{} 
  3.   fmt.Println(s1) 

執行結果。

在操作結構體時,即使沒有賦值,也會有默認值,所以不用擔心會報錯。

int默認值是0,string默認值是"",等。

總結

上述我們學習了Go語言基礎的結構體,先是回憶了map,map的優缺點,然後引入結構體。

講述了結構體如何創建,賦值,什麼是匿名結構體,直接通過&賦值結構體等。

本文轉載自微信公眾號「Go語言進階學習」,可以通過以下二維碼關注。轉載本文請聯繫Go語言進階學習公眾號。

【編輯推薦】

【責任編輯:

武曉燕

TEL:(010)68476606】

點讚 0

相關焦點

  • 快速上手系列-C語言之基礎篇(一)
    按照之前的計劃,這篇文章本該寫C語言簡介,包括一些歷史背景,發展狀況, 語言特點什麼的,這些東西著實比較囉嗦。吃飯用的筷子,到現在我都不知道它的由來,不知道它是在什麼歷史背景下誕生的有些東西還是有必要了解一下,比如,C語言所產生的代碼運行速度比彙編語言編寫的代碼運行速度稍慢一點,但還是有得一拼,同時C語言要比彙編語言編寫的代碼可讀性高,可移植性好。
  • 第六篇:C語言中結構體與文件操作相關知識點梳理
    前面總結過,C語言中的基本數據類型有四種,分別是整型、浮點型和字符型;後面又講到可以保存字符串的字符數組。但這遠遠不夠實際應用的需要。這就是本文要總結的第一個核心知識點:結構體。在C語言中結構體是對數據類型的無限擴展。程式設計師可以根據需要定義各種各樣的數據類型,即:結構體。
  • 解密 Go 語言之反射 reflect
    今天我們通過這篇文章來一一揭曉,以 Go 語言為例,了解反射到底為何物,其底層又是如何實現的。反射是什麼在計算機學中,反射是指電腦程式在運行時(runtime)可以訪問、檢測和修改它本身狀態或行為的一種能力。
  • Go語言的學習筆記(第二章)
    iotaiota是go語言的常量計數器,只能在常量的表達式中使用。const ( a, b = iota + 1, iota + 2 //1,2 c, d                      //2,3 e, f                      //3,4)Go語言基礎之基本數據類型
  • Go 語言:別再問我什麼是反射
    在 Go 語言中,空接口 interface{}是可以作為一切類型值的通用類型使用。所以這裡的接口值 interface value 可以理解為空接口變量值 interface{} value。srcType.Implements(dstType) { log.Fatalf("type %v that does not satisfy %v", srcType, dstType)}這也是grpc框架的基礎實現,因為這段代碼通常會是在程序的啟動階段所以對於程序的性能而言沒有任何影響。
  • VHDL結構體的行為描述法
    所謂結構體的行為描述(behavioral descriptions),即對設計實體按算法的路徑來描述。(2)從計算機領域而言,行為描述和高級程式語言類似,所以計算機業內人士通常稱之為高級描述。 當用順序執行結構體的行為描述時,設計工程師可為實體定義一組狀態時序機制,不需要互連表,無須關注實體的電路組織和門級實現,這些完全由EDA工具綜合生成,設計工程師只需注意正確的實體行為、準確的函數模型和精確的輸出結果。例1-6為比較器的行為描述。
  • 第一篇:C語言編程基礎語法
    本專欄系列分六篇,總結了C語言基礎知識的核心要點。教學視頻已上線,讀者可根據自身情況有選擇性地學習。01編程基礎C語言——貝爾實驗室、Dennis Ritchie屬於高級語言,更接近人類語言邏輯,需要編譯器編譯,執行依賴運行環境;但容易學習。其特點:模塊化編程程序設計,層次清晰;語句簡潔,提出程序庫概念;功能強大,系統、應用軟體均可開發;移植性好,適合不同的作業系統。除此之外,C語言還有豐富的運算符、數據結構等,程序設計自由度大,可以對硬體進行操作。
  • Go語言學習筆記之字符串一
    Go語言是一個年輕人,身上擁有c++,java,python等語言的特點。在網絡通信、並發和並行編程擁有極好的體驗,當然不僅僅在這上上面,還有網絡編程,web應用,應用下載等有著非常大的潛力。這裡列舉一些 Go 語言的特點: 簡化問題,易於學習 內存管理,簡潔語法,易於使用 快速編譯,高效開發 高效執行 並發支持,輕鬆駕馭, 靜態類型 標準類庫,規範統一 易於部署 文檔全面 免費開源學習go語言有幾天了,今天突然想到把學的寫成筆記,記錄一下。如有不正確的請指教。
  • Python使用ctypes模塊調用DLL函數之C語言數組與numpy數組傳遞
    在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,在提高軟體運行效率的同時,也可以充分利用目前市面上各種第三方的DLL庫函數,以擴充Python軟體的功能及應用領域,減少重複編寫代碼、重複造輪子的工作量,這也充分體現了Python語言作為一種膠水語言所特有的優勢
  • Go 語言的演化歷程 - OSCHINA - 中文開源技術交流社區
    其他一些語言影響和貫穿於Go的設計當中。還有一些來自其他語言的優點和缺點: C++, C#, Java, JavaScript, LISP, Python, Scala, …18、hello.go,Go 1版將我們帶到了今天。
  • 以實例跟我學C語言:如何求解一元二次方程的根
    注意:這是一篇關於C語言編程的基礎語法內容,C語言大神請繞過。在代碼設計中,可定義一個結構體Complex存儲該方程的根,在該結構體中包括實部和虛部兩個變量,如下所示:在程序中,定義兩個Complex類型的根x1和x2,當delta>=0時,兩個根的虛部為0,否則,分別求解兩個根的虛部值。
  • go 學習筆記之學習函數式編程前不要忘了函數基礎
    所以接下來我們一邊複習一邊學習函數的基本特點,為接下來理解函數式編程打下基礎,關於函數的基礎語言可參考 go 學習筆記之值得特別關注的基礎語法有哪些函數的基礎語法和高級特性下面以最基本四則運算為例,貫穿全文講解函數的基本語法和高級特性
  • C語言的指針,簡介
    與高級語言的long類型的大小是一致的。所以在java的JNI庫裡,如果需要把native層的C結構體的指針保存到java層,一般是定義一個long類型的變量。指針指向的變量,可以是普通變量、數組變量、結構體變量,以及數組元素、結構體的成員變量,還可以是指針變量。
  • 「C語言從入門到入土」必備C語言基礎筆記整理
    一、C語言1、什麼是C語言?C語言是人寫機器看的一種語言。C語言是高級語言中的低級語言。C語言貼近硬體。C語言的入門學習比較簡單。彙編語言——>B語言——>C語言2、C語言的特性首先C語言就是你的女朋友。無論你讓它幹什麼,它絕對不會自己找到方法。
  • Golang 基礎整理 這一篇就夠了
    一個方法就是一個包含了接受者的函數,接受者可以是命名類型或者結構體類型的一個值或者是一個指針。", "Google", "Go 語言教程", 6495407})    // 也可以使用 key => value 格式    fmt.Println(Books{title: "Go 語言", author: "Google", subject: "Go 語言教程", book_id: 6495407})    // 忽略的欄位為 0 或 空
  • 正點原子-戰艦V3第四章 STM32F1 基礎知識入門
    中斷優先級管理·4.6 MDK 中寄存器地址名稱映射分析·4.7 MDK 固件庫快速開發技巧4.1 MDK 下 C 語言基礎複習 這一節我們主要講解一下 C 語言基礎知識。C 語言知識博大精深,也不是我們三言兩語能講解清楚,同時我們相信學 STM32F4 這種級別 MCU 的用戶,C 語言基礎應該都是沒問題的。我們這裡主要是簡單的複習一下幾個 C 語言基礎知識點,引導那些 C 語言基礎知識不是很紮實的用戶能夠快速開發 STM32 程序。同時希望這些用戶能夠多去複習一下 C 語言基礎知識,C 語言畢竟是單片機開發中的必備基礎知識。
  • C語言基礎知識學習(一)
    C程序基礎1. 標識符在程序中使用的變量名、函數名、數組名、指針名、標號等稱為標識符.原先的C89標準中只有32個關鍵字然後在1999年之後進行了兩次技術修正,新出臺了C99標準新增加了5個關鍵字 分別是:restrict, inline, _Complex, _Imaginary, _Boolb) 預定義標識符包括C語言提供的庫函數
  • go 學習筆記之解讀什麼是defer延遲函數
    Go 語言中有個 defer 關鍵字,常用於實現延遲函數來保證關鍵代碼的最終執行,常言道: "未雨綢繆方可有備無患".延遲函數就是這麼一種機制,無論程序是正常返回還是異常報錯,只要存在延遲函數都能保證這部分關鍵邏輯最終執行,所以用來做些資源清理等操作再合適不過了.
  • R語言畫展基礎篇-折線圖
    做折線圖,以觀察兩棵樹的高度變化情況 #做一個基礎版本的折線圖plot(height_1 ~ months, type = "b")lines(height_2 ~ months, type = "b")
  • 快報:正式提案將泛型特性加入 Go 語言
    快報:正式提案將泛型特性加入 Go 語言 經歷九九八十一難,多年的不斷探討和 Go 語言愛好者們在社區中的強烈關注,且 Go 官方在 2020 年不斷放出消息。