真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言引用對象結構 go語言數(shù)據(jù)結構

講講go語言的結構體

作為C語言家族的一員,go和c一樣也支持結構體??梢灶惐扔趈ava的一個POJO。

站在用戶的角度思考問題,與客戶深入溝通,找到瓊中黎族網(wǎng)站設計與瓊中黎族網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設計與互聯(lián)網(wǎng)技術結合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都做網(wǎng)站、成都網(wǎng)站設計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、空間域名、網(wǎng)絡空間、企業(yè)郵箱。業(yè)務覆蓋瓊中黎族地區(qū)。

在學習定義結構體之前,先學習下定義一個新類型。

新類型 T1 是基于 Go 原生類型 int 定義的新自定義類型,而新類型 T2 則是 基于剛剛定義的類型 T1,定義的新類型。

這里要引入一個底層類型的概念。

如果一個新類型是基于某個 Go 原生類型定義的, 那么我們就叫 Go 原生類型為新類型的底層類型

在上面的例子中,int就是T1的底層類型。

但是T1不是T2的底層類型,只有原生類型才可以作為底層類型,所以T2的底層類型還是int

底層類型是很重要的,因為對兩個變量進行顯式的類型轉換,只有底層類型相同的變量間才能相互轉換。底層類型是判斷兩個類型本質上是否相同的根本。

這種類型定義方式通常用在 項目的漸進式重構,還有對已有包的二次封裝方面

類型別名表示新類型和原類型完全等價,實際上就是同一種類型。只不過名字不同而已。

一般我們都是定義一個有名的結構體。

字段名的大小寫決定了字段是否包外可用。只有大寫的字段可以被包外引用。

還有一個點提一下

如果換行來寫

Age: 66,后面這個都好不能省略

還有一個點,觀察e3的賦值

new返回的是一個指針。然后指針可以直接點號賦值。這說明go默認進行了取值操作

e3.Age 等價于 (*e3).Age

如上定義了一個空的結構體Empty。打印了元素e的內存大小是0。

有什么用呢?

基于空結構體類型內存零開銷這樣的特性,我們在日常 Go 開發(fā)中會經(jīng)常使用空 結構體類型元素,作為一種“事件”信息進行 Goroutine 之間的通信

這種以空結構體為元素類建立的 channel,是目前能實現(xiàn)的、內存占用最小的 Goroutine 間通信方式。

這種形式需要說的是幾個語法糖。

語法糖1:

對于結構體字段,可以省略字段名,只寫結構體名。默認字段名就是結構體名

這種方式稱為 嵌入字段

語法糖2:

如果是以嵌入字段形式寫的結構體

可以省略嵌入的Reader字段,而直接訪問ReaderName

此時book是一個各個屬性全是對應類型零值的一個實例。不是nil。這種情況在Go中稱為零值可用。不像java會導致npe

結構體定義時可以在字段后面追加標簽說明。

tag的格式為反單引號

tag的作用是可以使用[反射]來檢視字段的標簽信息。

具體的作用還要看使用的場景。

比如這里的tag是為了幫助 encoding/json 標準包在解析對象時可以利用的規(guī)則。比如omitempty表示該字段沒有值就不打印出來。

沒有類,C語言有結構體,那么Go的結構體有什么特別之處?

Go語言中沒有“類”的概念,也不支持“類”的繼承等面向對象的概念。Go語言中通過結構體的內嵌再配合接口比面向對象具有更高的擴展性和靈活性。

自定義類型

在Go語言中有一些基本的數(shù)據(jù)類型,如string、整型、浮點型、布爾等數(shù)據(jù)類型, Go語言中可以使用type關鍵字來定義自定義類型。

自定義類型是定義了一個全新的類型。我們可以基于內置的基本類型定義,也可以通過struct定義。例如:

通過Type關鍵字的定義,MyInt就是一種新的類型,它具有int的特性。

類型別名

類型別名是Go1.9版本添加的新功能。

類型別名規(guī)定:TypeAlias只是Type的別名,本質上TypeAlias與Type是同一個類型。就像一個孩子小時候有小名、乳名,上學后用學名,英語老師又會給他起英文名,但這些名字都指的是他本人。

type TypeAlias = Type

我們之前見過的rune和byte就是類型別名,他們的定義如下:

類型定義和類型別名的區(qū)別

類型別名與類型定義表面上看只有一個等號的差異,我們通過下面的這段代碼來理解它們之間的區(qū)別。

結果顯示a的類型是main.NewInt,表示main包下定義的NewInt類型。b的類型是int。MyInt類型只會在代碼中存在,編譯完成時并不會有MyInt類型。

Go語言中的基礎數(shù)據(jù)類型可以表示一些事物的基本屬性,但是當我們想表達一個事物的全部或部分屬性時,這時候再用單一的基本數(shù)據(jù)類型明顯就無法滿足需求了,Go語言提供了一種自定義數(shù)據(jù)類型,可以封裝多個基本數(shù)據(jù)類型,這種數(shù)據(jù)類型叫結構體,英文名稱struct。 也就是我們可以通過struct來定義自己的類型了。

Go語言中通過struct來實現(xiàn)面向對象。

結構體的定義

使用type和struct關鍵字來定義結構體,具體代碼格式如下:

其中:

舉個例子,我們定義一個Person(人)結構體,代碼如下:

同樣類型的字段也可以寫在一行,

這樣我們就擁有了一個person的自定義類型,它有name、city、age三個字段,分別表示姓名、城市和年齡。這樣我們使用這個person結構體就能夠很方便的在程序中表示和存儲人信息了。

語言內置的基礎數(shù)據(jù)類型是用來描述一個值的,而結構體是用來描述一組值的。比如一個人有名字、年齡和居住城市等,本質上是一種聚合型的數(shù)據(jù)類型

結構體實例化

只有當結構體實例化時,才會真正地分配內存。也就是必須實例化后才能使用結構體的字段。

基本實例化

舉個例子:

我們通過.來訪問結構體的字段(成員變量),例如p1.name和p1.age等。

匿名結構體

在定義一些臨時數(shù)據(jù)結構等場景下還可以使用匿名結構體。

創(chuàng)建指針類型結構體

我們還可以通過使用new關鍵字對結構體進行實例化,得到的是結構體的地址。 格式如下:

從打印的結果中我們可以看出p2是一個結構體指針。

需要注意的是在Go語言中支持對結構體指針直接使用.來訪問結構體的成員。

取結構體的地址實例化

使用對結構體進行取地址操作相當于對該結構體類型進行了一次new實例化操作。

p3.name = "七米"其實在底層是(*p3).name = "七米",這是Go語言幫我們實現(xiàn)的語法糖。

結構體初始化

沒有初始化的結構體,其成員變量都是對應其類型的零值。

使用鍵值對初始化

使用鍵值對對結構體進行初始化時,鍵對應結構體的字段,值對應該字段的初始值。

也可以對結構體指針進行鍵值對初始化,例如:

當某些字段沒有初始值的時候,該字段可以不寫。此時,沒有指定初始值的字段的值就是該字段類型的零值。

使用值的列表初始化

初始化結構體的時候可以簡寫,也就是初始化的時候不寫鍵,直接寫值:

使用這種格式初始化時,需要注意:

結構體內存布局

結構體占用一塊連續(xù)的內存。

輸出:

【進階知識點】關于Go語言中的內存對齊推薦閱讀:在 Go 中恰到好處的內存對齊

面試題

請問下面代碼的執(zhí)行結果是什么?

構造函數(shù)

Go語言的結構體沒有構造函數(shù),我們可以自己實現(xiàn)。 例如,下方的代碼就實現(xiàn)了一個person的構造函數(shù)。 因為struct是值類型,如果結構體比較復雜的話,值拷貝性能開銷會比較大,所以該構造函數(shù)返回的是結構體指針類型。

調用構造函數(shù)

方法和接收者

Go語言中的方法(Method)是一種作用于特定類型變量的函數(shù)。這種特定類型變量叫做接收者(Receiver)。接收者的概念就類似于其他語言中的this或者 self。

方法的定義格式如下:

其中,

舉個例子:

方法與函數(shù)的區(qū)別是,函數(shù)不屬于任何類型,方法屬于特定的類型。

指針類型的接收者

指針類型的接收者由一個結構體的指針組成,由于指針的特性,調用方法時修改接收者指針的任意成員變量,在方法結束后,修改都是有效的。這種方式就十分接近于其他語言中面向對象中的this或者self。 例如我們?yōu)镻erson添加一個SetAge方法,來修改實例變量的年齡。

調用該方法:

值類型的接收者

當方法作用于值類型接收者時,Go語言會在代碼運行時將接收者的值復制一份。在值類型接收者的方法中可以獲取接收者的成員值,但修改操作只是針對副本,無法修改接收者變量本身。

什么時候應該使用指針類型接收者

任意類型添加方法

在Go語言中,接收者的類型可以是任何類型,不僅僅是結構體,任何類型都可以擁有方法。 舉個例子,我們基于內置的int類型使用type關鍵字可以定義新的自定義類型,然后為我們的自定義類型添加方法。

注意事項: 非本地類型不能定義方法,也就是說我們不能給別的包的類型定義方法。

結構體的匿名字段

匿名字段默認采用類型名作為字段名,結構體要求字段名稱必須唯一,因此一個結構體中同種類型的匿名字段只能有一個。

嵌套結構體

一個結構體中可以嵌套包含另一個結構體或結構體指針。

嵌套匿名結構體

當訪問結構體成員時會先在結構體中查找該字段,找不到再去匿名結構體中查找。

嵌套結構體的字段名沖突

嵌套結構體內部可能存在相同的字段名。這個時候為了避免歧義需要指定具體的內嵌結構體的字段。

結構體的“繼承”

Go語言中使用結構體也可以實現(xiàn)其他編程語言中面向對象的繼承。

結構體字段的可見性

結構體中字段大寫開頭表示可公開訪問,小寫表示私有(僅在定義當前結構體的包中可訪問)。

結構體與JSON序列化

JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。易于人閱讀和編寫。同時也易于機器解析和生成。JSON鍵值對是用來保存JS對象的一種方式,鍵/值對組合中的鍵名寫在前面并用雙引號""包裹,使用冒號:分隔,然后緊接著值;多個鍵值之間使用英文,分隔。

結構體標簽(Tag)

Tag是結構體的元信息,可以在運行的時候通過反射的機制讀取出來。 Tag在結構體字段的后方定義,由一對反引號包裹起來,具體的格式如下:

`key1:"value1" key2:"value2"`

結構體標簽由一個或多個鍵值對組成。鍵與值使用冒號分隔,值用雙引號括起來。鍵值對之間使用一個空格分隔。 注意事項: 為結構體編寫Tag時,必須嚴格遵守鍵值對的規(guī)則。結構體標簽的解析代碼的容錯能力很差,一旦格式寫錯,編譯和運行時都不會提示任何錯誤,通過反射也無法正確取值。例如不要在key和value之間添加空格。

例如我們?yōu)镾tudent結構體的每個字段定義json序列化時使用的Tag:

Go語言中new和 make的區(qū)別詳解

1、new 的主要特性

首先 new 是內建函數(shù),定義也很簡單:

func new(Type) *Type

內建函數(shù) new 用來分配內存,第一個參數(shù)是一個類型,不是一個值,返回值是一個指向新分配類型零值的指針

實現(xiàn)一個類似 new 的功能:

func newInt() *int {

var i int

return i

}

someInt := newInt()

函數(shù)的功能跟 someInt := new(int) 一模一樣。定義 new 開頭的函數(shù)時,出于約定也應該返回類型的指針。

2、make 的主要特性

make 也是內建函數(shù),定義比 new 多了一個參數(shù),返回值也不同:

func make(Type, size IntegerType) Type

內建函數(shù) make 用來為 slice,map 或 chan 類型分配內存和初始化一個對象(注意:只能用在這三種類型上),跟 new 類似,第一個參數(shù)也是一個類型而不是一個值,跟 new 不同的是,make 返回類型的引用而不是指針,而返回值也依賴于具體傳入的類型,具體說明如下:

Slice: 第二個參數(shù) size 指定了長度,容量和長度相同。

可以傳入第三個參數(shù)來指定不同的容量值,但必須不能比長度值小。

比如 make([]int, 0, 10)

Map: 根據(jù) size 大小來初始化分配內存,不過分配后的 map 長度為 0,如果 size 被忽略了,那么會在初始化分配內存時分配一個小尺寸的內存

Channel: 管道緩沖區(qū)依據(jù)緩沖區(qū)容量被初始化。如果容量為 0 或者忽略容量,管道沒有緩沖區(qū)。

3、總結

new 的作用是初始化一個指向類型的指針(*T),make 的作用是為 slice,map 或 chan 初始化并返回引用(T)。

go語言中的面向對象

類的成員函數(shù) 有時也稱為 方法 。因此,方法可以認為是傳統(tǒng)面向對象中 類的成員函數(shù) 。不同的是,go中方法可以綁定到任何類型上,但是成員函數(shù)只能屬于類。

用來描述主調方法,就像向對象發(fā)送消息。

不允許本身是指針的類型進行方法聲明。

與繼承的不同,組合中的順序也是無意義的。

參考一等函數(shù),方法做變量

首字母大小寫,要封裝一個對象,只能通過結構體。


本文題目:go語言引用對象結構 go語言數(shù)據(jù)結構
分享路徑:http://weahome.cn/article/docshej.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部