bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

golang中值類(lèi)型/指針類(lèi)型的變量區(qū)別是什么-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)golang中值類(lèi)型/指針類(lèi)型的變量區(qū)別是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)服務(wù)商,為中小企業(yè)提供網(wǎng)站制作、網(wǎng)站設(shè)計(jì)服務(wù),網(wǎng)站設(shè)計(jì),網(wǎng)站托管等一站式綜合服務(wù)型公司,專(zhuān)業(yè)打造企業(yè)形象網(wǎng)站,讓您在眾多競(jìng)爭(zhēng)對(duì)手中脫穎而出創(chuàng)新互聯(lián)。

前言

值類(lèi)型:所有像int、float、bool和string這些類(lèi)型都屬于值類(lèi)型,使用這些類(lèi)型的變量直接指向存在內(nèi)存中的值,值類(lèi)型的變量的值存儲(chǔ)在棧中。當(dāng)使用等號(hào)=將一個(gè)變量的值賦給另一個(gè)變量時(shí),如 j = i ,實(shí)際上是在內(nèi)存中將 i 的值進(jìn)行了拷貝。可以通過(guò) &i 獲取變量 i 的內(nèi)存地址

指針類(lèi)型:簡(jiǎn)單地說(shuō)go語(yǔ)言的指針類(lèi)型和C/C++的指針類(lèi)型用法是一樣的,除了出去安全性的考慮,go語(yǔ)言增加了一些限制,包括如下幾條:

  • 不同類(lèi)型的指針不能互相轉(zhuǎn)化,例如*int, int32, 以及int64

  • 任何普通指針類(lèi)型*T和uintptr之間不能互相轉(zhuǎn)化

  • 指針變量不能進(jìn)行運(yùn)算, 比如C/C++里面的++, --運(yùn)算

下面將給大家詳細(xì)介紹golang中值類(lèi)型/指針類(lèi)型的變量的一些區(qū)別,下面話(huà)不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。

值類(lèi)型的變量和指針類(lèi)型的變量

先聲明一個(gè)結(jié)構(gòu)體:

type T struct {
 Name string
}
func (t T) M1() {
 t.Name = "name1"
}
func (t *T) M2() {
 t.Name = "name2"
}

M1() 的接收者是值類(lèi)型 T, M2() 的接收者是值類(lèi)型 *T , 兩個(gè)方法內(nèi)都是改變Name值。

下面聲明一個(gè) T 類(lèi)型的變量,并調(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

下面猜測(cè)一下go會(huì)怎么處理。

先來(lái)約定一下:接收者可以看作是函數(shù)的第一個(gè)參數(shù),即這樣的: func M1(t T) , func M2(t *T) 。 go不是面向?qū)ο蟮恼Z(yǔ)言,所以用那種看起來(lái)像面向?qū)ο蟮恼Z(yǔ)法來(lái)理解可能有偏差。

當(dāng)調(diào)用 t1.M1() 時(shí)相當(dāng)于 M1(t1) ,實(shí)參和行參都是類(lèi)型 T,可以接受。此時(shí)在M1()中的t只是t1的值拷貝,所以M1()的修改影響不到t1。

當(dāng)調(diào)用 t1.M2() => M2(t1) ,這是將 T 類(lèi)型傳給了 *T 類(lèi)型,go可能會(huì)取 t1 的地址傳進(jìn)去: M2(&t1) 。所以 M2() 的修改可以影響 t1 。

類(lèi)型的變量這兩個(gè)方法都是擁有的。

下面聲明一個(gè) *T 類(lèi)型的變量,并調(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 是指針類(lèi)型, 取 t2 的值并拷貝一份傳給 M1。

t2.M2() => M2(t2) ,都是指針類(lèi)型,不需要轉(zhuǎn)換。

*T 類(lèi)型的變量也是擁有這兩個(gè)方法的。

傳給接口會(huì)怎樣?

先聲明一個(gè)接口

type Intf interface {
 M1()
 M2()
}

使用:

 var t1 T = T{"t1"}
 t1.M1()
 t1.M2()
 var t2 Intf = t1
 t2.M1()
 t2.M2()

報(bào)錯(cuò):

./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 這一行報(bào)錯(cuò)。

t1 是有 M2() 方法的,但是為什么傳給 t2 時(shí)傳不過(guò)去呢?

簡(jiǎn)單來(lái)說(shuō),按照接口的理論:傳過(guò)去【賦值】的對(duì)象必須實(shí)現(xiàn)了接口要求的方法,而t1沒(méi)有實(shí)現(xiàn)M2() ,t1的指針實(shí)現(xiàn)了M2() 。另外和c語(yǔ)言一樣,函數(shù)名本身就是指針

當(dāng)把 var t2 Intf = t1 修改為 var t2 Intf = &t1 時(shí)編譯通過(guò),此時(shí) t2 獲得的是 t1 的地址, t2.M2() 的修改可以影響到 t1 了。

如果聲明一個(gè)方法 func f(t Intf) , 參數(shù)的傳遞和上面的直接賦值是一樣的情況。

嵌套類(lèi)型

聲明一個(gè)類(lèi)型 S,將 T 嵌入進(jìn)去

type S struct { T }

使用下面的例子測(cè)試一下:

 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 的值沒(méi)有改變,因?yàn)槲覀兦度氲氖?T 類(lèi)型,所以 S{t1} 的時(shí)候是將 t1 拷貝了一份。

假如我們將 s 賦值給 Intf 接口會(huì)怎么樣呢?

 var intf Intf = s 
 intf.M1() 
 intf.M2()

報(bào)錯(cuò):

cannot use s (type S) as type Intf in assignment: S does not implement Intf (M2 method has pointer receiver)

還是 M2() 的問(wèn)題,因?yàn)?s 此時(shí)還是值類(lèi)型。

var intf Intf = &s 這樣的話(huà)編譯通過(guò)了,如果在 intf.M2() 中改變了 Name 的值, s.Name 被改變了,但是 t1.Name 依然沒(méi)變,因?yàn)楝F(xiàn)在 t1 和 s 已經(jīng)沒(méi)有聯(lián)系了。

下面嵌入 *T 試試:

type S struct { *T }

使用時(shí)這樣:

 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 的值變了,因?yàn)槲覀儚?fù)制的是指針。

接著賦值給接口試試:

 var intf Intf = s i
 ntf.M1() 
 intf.M2() 
 fmt.Println(s.Name)

編譯沒(méi)有報(bào)錯(cuò)。這里我們傳遞給 intf 的是值類(lèi)型而不是指針,為什么可以通過(guò)呢?

拷貝 s 的時(shí)候里面的 T 是指針類(lèi)型,所以調(diào)用 M2() 的時(shí)候傳遞進(jìn)去的是一個(gè)指針。

var intf Intf = &s 的效果和上面一樣。

關(guān)于“golang中值類(lèi)型/指針類(lèi)型的變量區(qū)別是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線(xiàn),公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。

當(dāng)前標(biāo)題:golang中值類(lèi)型/指針類(lèi)型的變量區(qū)別是什么-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)網(wǎng)址:http://vcdvsql.cn/article10/iscgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開(kāi)發(fā)域名注冊(cè)做網(wǎng)站動(dòng)態(tài)網(wǎng)站全網(wǎng)營(yíng)銷(xiāo)推廣網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化