Go語言的類型系統

來源:互聯網
上載者:User

Go語言允許使用者定義型別。當使用者聲明一個類型時,這個聲明就給編譯器提供了一個架構,告知必要的記憶體大小和資訊。

聲明結構類型

type user struct {    name  string    email string}

上述代碼聲明的結構類型有2個欄位,每個欄位都基於一個內建類型。一旦聲明了類型,就可以使用這個類型建立值。

使用結構型別宣告變數
var zuckjet user

我們用關鍵字var建立了類型為user且名為zuckjet的變數。當聲明變數時,這個變數對應的值總是會被初始化。這個值要麼是用指定的值初始化,要麼用零值來初始化。對數值來類型來說,零值是0;對字串來說,零值是Null 字元串。
下面我們來看一下如何聲明一個user類型的變數,並使用某個非零值作為初始值。

zuckberg := user{  name: "zuckberg"  email: "zuckjet@gmail.com"}

方法

方法能給使用者定義的類型添加新的行為。方法實際上也是函數,知識在聲明的時,在關鍵字func和方法名之間增加了一個參數。

func (u user) notify() {  fmt.Printf(u.name)}

在上面的代碼中,關鍵字func和函數名之間的參數被稱作接收者,將函數與接收者的類型綁在一起。如果一個函數有接收者,這個函數就被稱為方法。下面我們來看一個簡單的demo:

package mainimport (    "fmt")type user struct {    name  string    email string}func (u user) notify() {    fmt.Println(u.name)}func main() {    bill := user{"zuckjet", "zuckjet@gmail.com"}    bill.notify()}// zuckjet

首先我們頂一個一個user類型,然後notify使用值接收者實現了一個方法,最後我們通過建立一個user類型的變數bill並調用notify方法。
當我們通過bill.notify()調用方法的時候,notify方法中的u變數的值就等同於變數bill。為什麼我說等同於變數bill呢?因為
使用值接收者聲明方法,調用時會使用這個值的一個副本來執行。
我們稍微修改一下上面的代碼即可驗證:

package mainimport (    "fmt")type user struct {    name  string    email string}func (u user) notify() {    u.name = "zuckberg"    fmt.Println(u.name)}func main() {    bill := user{"zuckjet", "zuckjet@gmail.com"}    bill.notify()    fmt.Println(bill.name)}// zuckberg// zuckjet

因為變數u是bill的一個副本,所以改變它裡面屬性的值,是不會影響bill本身的值的。
值得注意的是,在Go語言中我們還可以使用指標來調用值接收者聲明的方法,儘管這看起來似乎不太合理。
我們看一下下面的代碼:

package mainimport (    "fmt")type user struct {    name  string    email string}func (u user) notify() {    fmt.Println(u.name)}func main() {    bill := &user{"zuckjet", "zuckjet@gmail.com"}    bill.notify()}// zuckjet

這次我們定義的變數bill是指標類型的,用指標類型的變數來調用noify方法的時候,依然能夠輸出bill的name屬性值。看到這裡或許你有些疑惑,不是說方法notify中的變數u就等同於變數bill嗎,為啥bill是一個指標類型的時候還能夠正確輸出name屬性值呢。其實,我們可以認為Go在背後替我們做了如下操作:

(*bill).notify()

上面我們講述的是使用值接受者聲明方法,除此之外我們還可以使用指標接收者聲明方法。我們來看下面的代碼:

package mainimport (    "fmt")type user struct {    name  string    email string}func (u *user) notify() {    fmt.Println(u.name)}func main() {    bill := user{"zuckjet", "zuckjet@gmail.com"}    bill.notify()}// zuckjet

同樣在調用notify方法時,Go在背後做了這樣一件事情:

(&bill).notify()

當把上面的notify()方法改造為:

func (u *user) notify() {    fmt.Println(u.name)    fmt.Println(&u)    fmt.Println(*u)    fmt.Println(u)}// 輸出結果zuckjet0xc420088018{zuckjet zuckjet@gmail.com}&{zuckjet zuckjet@gmail.com}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.