這篇文章將為大家詳細講解有關(guān)golang中值類型/指針類型的變量區(qū)別是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)網(wǎng)站建設(shè)服務(wù)商,為中小企業(yè)提供網(wǎng)站制作、網(wǎng)站設(shè)計服務(wù),網(wǎng)站設(shè)計,網(wǎng)站托管等一站式綜合服務(wù)型公司,專業(yè)打造企業(yè)形象網(wǎng)站,讓您在眾多競爭對手中脫穎而出創(chuàng)新互聯(lián)。前言
值類型:所有像int、float、bool和string這些類型都屬于值類型,使用這些類型的變量直接指向存在內(nèi)存中的值,值類型的變量的值存儲在棧中。當(dāng)使用等號=將一個變量的值賦給另一個變量時,如 j = i ,實際上是在內(nèi)存中將 i 的值進行了拷貝??梢酝ㄟ^ &i 獲取變量 i 的內(nèi)存地址
指針類型:簡單地說go語言的指針類型和C/C++的指針類型用法是一樣的,除了出去安全性的考慮,go語言增加了一些限制,包括如下幾條:
不同類型的指針不能互相轉(zhuǎn)化,例如*int, int32, 以及int64
任何普通指針類型*T和uintptr之間不能互相轉(zhuǎn)化
指針變量不能進行運算, 比如C/C++里面的++, --運算
下面將給大家詳細介紹golang中值類型/指針類型的變量的一些區(qū)別,下面話不多說了,來一起看看詳細的介紹吧。
值類型的變量和指針類型的變量
先聲明一個結(jié)構(gòu)體:
type T struct { Name string } func (t T) M1() { t.Name = "name1" } func (t *T) M2() { t.Name = "name2" }
M1()
的接收者是值類型 T, M2()
的接收者是值類型 *T , 兩個方法內(nèi)都是改變Name值。
下面聲明一個 T 類型的變量,并調(diào)用 M1()
和 M2()
。
t1 := T{"t1"} fmt.Println("M1調(diào)用前:", t1.Name) t1.M1() fmt.Println("M1調(diào)用后:", t1.Name) fmt.Println("M2調(diào)用前:", t1.Name) t1.M2() fmt.Println("M2調(diào)用后:", t1.Name)
輸出結(jié)果為:
M1調(diào)用前: t1
M1調(diào)用后: t1
M2調(diào)用前: t1
M2調(diào)用后: name2
下面猜測一下go會怎么處理。
先來約定一下:接收者可以看作是函數(shù)的第一個參數(shù),即這樣的: func M1(t T)
, func M2(t *T)
。 go不是面向?qū)ο蟮恼Z言,所以用那種看起來像面向?qū)ο蟮恼Z法來理解可能有偏差。
當(dāng)調(diào)用 t1.M1()
時相當(dāng)于 M1(t1)
,實參和行參都是類型 T,可以接受。此時在M1()
中的t只是t1的值拷貝,所以M1()
的修改影響不到t1。
當(dāng)調(diào)用 t1.M2() => M2(t1)
,這是將 T 類型傳給了 *T 類型,go可能會取 t1 的地址傳進去: M2(&t1)
。所以 M2()
的修改可以影響 t1 。
類型的變量這兩個方法都是擁有的。
下面聲明一個 *T 類型的變量,并調(diào)用 M1()
和 M2()
。
t2 := &T{"t2"} fmt.Println("M1調(diào)用前:", t2.Name) t2.M1() fmt.Println("M1調(diào)用后:", t2.Name) fmt.Println("M2調(diào)用前:", t2.Name) t2.M2() fmt.Println("M2調(diào)用后:", t2.Name)
輸出結(jié)果為:
M1調(diào)用前: t2
M1調(diào)用后: t2
M2調(diào)用前: t2
M2調(diào)用后: name2
t2.M1() => M1(t2)
, t2 是指針類型, 取 t2 的值并拷貝一份傳給 M1。
t2.M2() => M2(t2)
,都是指針類型,不需要轉(zhuǎn)換。
*T 類型的變量也是擁有這兩個方法的。
傳給接口會怎樣?
先聲明一個接口
type Intf interface { M1() M2() }
使用:
var t1 T = T{"t1"} t1.M1() t1.M2() var t2 Intf = t1 t2.M1() t2.M2()
報錯:
./main.go:9: cannot use t1 (type T) as type Intf in assignment:
T does not implement Intf (M2 method has pointer receiver)
var t2 Intf = t1
這一行報錯。
t1 是有 M2()
方法的,但是為什么傳給 t2 時傳不過去呢?
簡單來說,按照接口的理論:傳過去【賦值】的對象必須實現(xiàn)了接口要求的方法,而t1沒有實現(xiàn)M2()
,t1的指針實現(xiàn)了M2()
。另外和c語言一樣,函數(shù)名本身就是指針
當(dāng)把 var t2 Intf = t1
修改為 var t2 Intf = &t1
時編譯通過,此時 t2 獲得的是 t1 的地址, t2.M2()
的修改可以影響到 t1 了。
如果聲明一個方法 func f(t Intf)
, 參數(shù)的傳遞和上面的直接賦值是一樣的情況。
嵌套類型
聲明一個類型 S,將 T 嵌入進去
type S struct { T }
使用下面的例子測試一下:
t1 := T{"t1"} s := S{t1} fmt.Println("M1調(diào)用前:", s.Name) s.M1() fmt.Println("M1調(diào)用后:", s.Name) fmt.Println("M2調(diào)用前:", s.Name) s.M2() fmt.Println("M2調(diào)用后:", s.Name) fmt.Println(t1.Name)
輸出:
M1調(diào)用前: t1
M1調(diào)用后: t1
M2調(diào)用前: t1
M2調(diào)用后: name2
t1
將 T 嵌入 S, 那么 T 擁有的方法和屬性 S 也是擁有的,但是接收者卻不是 S 而是 T。
所以 s.M1()
相當(dāng)于 M1(t1)
而不是 M1(s)
。
最后 t1 的值沒有改變,因為我們嵌入的是 T 類型,所以 S{t1} 的時候是將 t1 拷貝了一份。
假如我們將 s 賦值給 Intf 接口會怎么樣呢?
var intf Intf = s intf.M1() intf.M2()
報錯:
cannot use s (type S) as type Intf in assignment: S does not implement Intf (M2 method has pointer receiver)
還是 M2()
的問題,因為 s 此時還是值類型。
var intf Intf = &s
這樣的話編譯通過了,如果在 intf.M2()
中改變了 Name 的值, s.Name
被改變了,但是 t1.Name
依然沒變,因為現(xiàn)在 t1 和 s 已經(jīng)沒有聯(lián)系了。
下面嵌入 *T 試試:
type S struct { *T }
使用時這樣:
t1 := T{"t1"} s := S{&t1} fmt.Println("M1調(diào)用前:", s.Name) s.M1() fmt.Println("M1調(diào)用后:", s.Name) fmt.Println("M2調(diào)用前:", s.Name) s.M2() fmt.Println("M2調(diào)用后:", s.Name) fmt.Println(t1.Name)
M1調(diào)用前: t1
M1調(diào)用后: t1
M2調(diào)用前: t1
M2調(diào)用后: name2
name2
惟一的區(qū)別是最后 t1 的值變了,因為我們復(fù)制的是指針。
接著賦值給接口試試:
var intf Intf = s i ntf.M1() intf.M2() fmt.Println(s.Name)
編譯沒有報錯。這里我們傳遞給 intf 的是值類型而不是指針,為什么可以通過呢?
拷貝 s 的時候里面的 T 是指針類型,所以調(diào)用 M2()
的時候傳遞進去的是一個指針。
var intf Intf = &s
的效果和上面一樣。
關(guān)于“golang中值類型/指針類型的變量區(qū)別是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
當(dāng)前標(biāo)題:golang中值類型/指針類型的變量區(qū)別是什么-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://jinyejixie.com/article10/iscgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、域名注冊、做網(wǎng)站、動態(tài)網(wǎng)站、全網(wǎng)營銷推廣、網(wǎng)站維護
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容