首頁 後端開發 Golang Go語言結構體與初始化圖文詳解

Go語言結構體與初始化圖文詳解

Jan 09, 2020 pm 05:54 PM
go語言

Go語言結構體與初始化圖文詳解

Go 透過型別別名(alias types)和結構體的形式支援使用者自訂類型。

結構體是複合類型,當需要定義類型,它由一系列屬性組成,每個屬性都有自己的類型和值的時候,就應該使用結構體,它把資料聚集在一起。

結構體也是值類型,因此可以透過 new 函數來建立

組成結構體類型的那些資料成為欄位(fields)。每個欄位都有一個類型和一個名字;在一個結構體中,欄位名字必須是唯一的。

一,結構體定義

結構體定義的一般方式如下:

type identifier struct {   
   field type1
    field type2}
登入後複製

type T struct {a, b int} 也是合法的語法,它更適用於簡單的結構體

結構體裡的字段都有名字,像field1、field2 等,如果字段在代碼中從來也不會被用到,那麼可以命名它為_。

結構體類型和欄位的命名遵循可見性規則,所以可能存在一個結構體類型的某些欄位是導出的,而有些則沒有導出。

結構體的欄位可以是任何類型,甚至是結構體本身,也可以是函數或介面。可以宣告結構體類型的一個變量,然後像下面這樣給它的字段賦值:

var s T
s.a = 5
s.b = 8
登入後複製

數組也可以看作是一種結構體類型,不過它使用下標而不是具名的字段

二,初始化

方式一:透過var 宣告結構體

在Go 語言中當一個變數被宣告的時候,系統會自動初始化它的預設值,例如int 被初始化為0,指標為nil。
var 宣告同樣也會為結構體類型的資料分配內存,所以我們才能像上一段程式碼中那樣,在宣告了 var s T 之後就能直接給他的欄位進行賦值

#方式二:使用new

使用new 函數給一個新的結構體變數分配內存,它會傳回指向已分配記憶體的指標:var t *T = new(T)。

type struct1 struct {
    i1 int
    f1 float32
    str string}func main() {
    ms := new(struct1)
    ms.i1 = 10
    ms.f1 = 15.5
    ms.str= "Chris"

    fmt.Printf("The int is: %d\n", ms.i1)
    fmt.Printf("The float is: %f\n", ms.f1)
    fmt.Printf("The string is: %s\n", ms.str)
    fmt.Println(ms)
}
登入後複製

與物件導向語言相同,使用點運算子可以給欄位賦值:structname.fieldname = value。

同樣的,使用點操作子可以取得結構體欄位的值:structname.fieldname。

方式三:使用字面量

type Person struct {
    name string
    age int
    address string
}

func main() {
    var p1 Person
    p1 = Person{"lisi", 30, "shanghai"}   //方式A
    p2 := Person{address:"beijing", age:25, name:"wangwu"} //方式B
    p3 := Person{address:"NewYork"} //方式C
}
登入後複製

在(方式A)中,值必須以結構體定義時欄位在結構體定義時的順序給出。 (方式B)是在值前面加上了欄位名稱和冒號,這種方式下值的順序不必一致,並且某些欄位還可以被忽略掉,就想(方式C)那樣。

除了上面這三種方式外,還有一個初始化結構體實體更簡短和常用的方式,如下:

ms := &Person{"name", 20, "bj"}
ms2 := &Person{name:"zhangsan"}
登入後複製

&Person{a, b, c} 是一種簡寫,底層仍會呼叫 new(),這裡值的順序必須按照字段順序來寫,同樣它也可以使用在值前面加上字段名和冒號的寫法(見上文的方式B,C)。

表達式 new(Type) 和 &Type{} 是等價的。

三,幾種初始化方式之間的差異

#到目前為止,我們已經了解了三種初始化結構體的方式:

//第一种,在Go语言中,可以直接以 var 的方式声明结构体即可完成实例化
var t T
t.a = 1
t.b = 2

//第二种,使用 new() 实例化
t := new(T)

//第三种,使用字面量初始化
t := T{a, b}
t := &T{} //等效于 new(T)
登入後複製

使用 var t T 會給t 分配內存,並零值化內存,但是這個時候的t 的類型是T

使用new 關鍵字時 t := new(T) ,變數t 則是指向T 的指標

從記憶體佈局來看,我們就能看出這三種初始化方式的差異:

使用var 宣告:

Go語言結構體與初始化圖文詳解

使用new 初始化:

Go語言結構體與初始化圖文詳解

使用結構體字面量初始化:

Go語言結構體與初始化圖文詳解

下面來看一個具體的例子:

package main
import "fmt"

type Person struct {
 name string
 age int
}

func main() {
 var p1 Person
 p1.name = "zhangsan"
 p1.age = 18
 fmt.Printf("This is %s, %d years old\n", p1.name, p1.age)

 p2 := new(Person)
 p2.name = "lisi"
 p2.age = 20
 (*p2).age = 23 //这种写法也是合法的
 fmt.Printf("This is %s, %d years old\n", p2.name, p2.age)

 p3 := Person{"wangwu", 25}
 fmt.Printf("This is %s, %d years old\n", p3.name, p3.age)
}
登入後複製

輸出:

This is zhangsan, 18 years old
This is lisi, 23 years old
This is wangwu, 25 years old
登入後複製

上面範例的第二種情況,雖然p2 是指標類型,但我們還是可以像 p2.age = 23 這樣賦值,不需要像C 那樣使用 -> 運算子,Go 會自動進行轉換。

注意也可以先透過 * 運算子來取得指標所指向的內容,再進行賦值:(*p2).age = 23。

結構體的記憶體佈局

#

Go 语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。不像 Java 中的引用类型,一个对象和它里面包含的对象可能会在不同的内存空间中,这点和 Go 语言中的指针很像。

下面的例子清晰地说明了这些情况:

type Rect1 struct {Min, Max Point }
type Rect2 struct {Min, Max *Point }
登入後複製

Go語言結構體與初始化圖文詳解

更多go语言知识请关注PHP中文网go语言教程栏目。

以上是Go語言結構體與初始化圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? 在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? Apr 02, 2025 pm 02:03 PM

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Apr 02, 2025 pm 12:57 PM

Go語言中結構體定義的兩種方式:var與type關鍵字的差異Go語言在定義結構體時,經常會看到兩種不同的寫法:一�...

使用 sql.Open 時,DSN 傳空為什麼不報錯? 使用 sql.Open 時,DSN 傳空為什麼不報錯? Apr 02, 2025 pm 12:54 PM

使用sql.Open時,DSN傳空為什麼不報錯?在Go語言中,sql.Open...

See all articles