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

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

Go語(yǔ)言之類型

Go語(yǔ)言是一種靜態(tài)類型的編程語(yǔ)言,所以在編譯器進(jìn)行編譯的時(shí)候,就要知道每個(gè)值的類型,這樣編譯器就知道要為這個(gè)值分配多少內(nèi)存,并且知道這段分配的內(nèi)存表示什么。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、臨渭區(qū)ssl等。為上千多家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的臨渭區(qū)網(wǎng)站制作公司


提前知道值的類型的好處有很多,比如編譯器可以合理地使用這些值,可以進(jìn)一步優(yōu)化代碼,提高執(zhí)行的效率,減少bug等。


基本類型


基本類型是Go語(yǔ)言自帶的類型,比如數(shù)值類型、浮點(diǎn)類型、字符類型以及布爾類型。它們本質(zhì)上是原始類型,也就是不可改變的,所以對(duì)它們進(jìn)行操作,一般都會(huì)返回一個(gè)新創(chuàng)建的值。所以把這些值傳遞給函數(shù)時(shí),其實(shí)傳遞的是一個(gè)值的副本。


func main() {
    name:="張三"
    fmt.Println(modify(name))
    fmt.Println(name)
}

func modify(s string) string{
    s=s+s
    return s
}
張三張三
張三


以上是一個(gè)操作字符串的例子。通過(guò)打印的結(jié)果,可以看到,本來(lái)name的值并沒(méi)有被改變,也就是說(shuō),我們傳遞的時(shí)一個(gè)副本,并且返回一個(gè)新創(chuàng)建的字符串。


因?yàn)榛绢愋褪强截惖闹?,并且在?duì)它進(jìn)行操作的時(shí)候,生成的也是新創(chuàng)建的值,所以這些類型在多線程里是安全的,我們不用擔(dān)心一個(gè)線程的修改影響了另外一個(gè)線程的數(shù)據(jù)。


引用類型


引用類型和原始的基本類型恰恰相反,它的修改可以影響到任何引用到它的變量。在Go語(yǔ)言中,引用類型有切片、map、接口、函數(shù)類型以及chan。


引用類型之所以可以引用,是因?yàn)槲覀儎?chuàng)建的引用類型變量,其實(shí)是一個(gè)標(biāo)頭值,標(biāo)頭值里包含一個(gè)指針,指向底層的數(shù)據(jù)結(jié)構(gòu)。當(dāng)我們?cè)诤瘮?shù)中傳遞引用類型時(shí),其實(shí)傳遞的是這個(gè)標(biāo)頭值的副本,它所指向的底層結(jié)構(gòu)并沒(méi)有被復(fù)制傳遞,這也是引用類型傳遞高效的原因。


本質(zhì)上,我們可以理解函數(shù)的傳遞都是值傳遞,只不過(guò)引用類型傳遞的是一個(gè)指向底層數(shù)據(jù)的指針。所以我們?cè)诓僮鞯臅r(shí)候,可以修改共享的底層數(shù)據(jù)的值,進(jìn)而影響到所有引用到這個(gè)共享底層數(shù)據(jù)的變量。


func main() {
    ages := map[string]int{"張三": 20}
    fmt.Println(ages)
    modify(ages)
    fmt.Println(ages)
}

func modify(m map[string]int) {
    m["張三"] = 10
}


這是一個(gè)很明顯的修改引用類型的例子,函數(shù)modify的修改,會(huì)影響到原來(lái)變量ages的值。


結(jié)構(gòu)類型


結(jié)構(gòu)類型是用來(lái)描述一組值的,比如一個(gè)人有身高、體重、名字和年齡等本質(zhì)上是一種聚合型的數(shù)據(jù)類型。


type person struct {
    age int
    name string
}


定義一個(gè)結(jié)構(gòu)體的類型,要通過(guò)type關(guān)鍵字和類型struct進(jìn)行聲明,以上我們就定義了一個(gè)結(jié)構(gòu)體類型person,它有agename這兩個(gè)字段數(shù)據(jù)。


結(jié)構(gòu)體類型定義好之后,就可以進(jìn)行使用了,我們可以用過(guò)var關(guān)鍵字聲明一個(gè)結(jié)構(gòu)體類型的變量。


var p person


這種聲明的方式,會(huì)對(duì)結(jié)構(gòu)體person里的數(shù)據(jù)類型默認(rèn)初始化,也就是使用它們類型的零值。如果要?jiǎng)?chuàng)建一個(gè)結(jié)構(gòu)體變量并初始化其為零值時(shí),這種var方式最常用。


如果我們需要指定非零值,就可以使用我們字面量方式了。


jim := person{10,"Jim"}


示例中我們就為其指定了值,注意這個(gè)值的順序很重要,必須和結(jié)構(gòu)體里聲明字段的順序一致。當(dāng)然我們也可以不按順序,但是這時(shí)候我們必須為字段指定值。


jim := person{name:"Jim",age:10}


使用冒號(hào):分開(kāi)字段名和字段值即可,這樣我們就不用嚴(yán)格的按照定義的順序了。


除了基本的原始類型外,結(jié)構(gòu)體內(nèi)的值也可以是引用類型,或者自己定義的其他類型。具體選擇類型,要根據(jù)實(shí)際情況,比如是否允許修改值本身,如果允許的話,可以選擇引用類型;如果不允許的話,則需要使用基本類型。


函數(shù)傳參是值傳遞,所以對(duì)于結(jié)構(gòu)體來(lái)說(shuō)也不例外,結(jié)構(gòu)體傳遞的是其本身以及里面的值的拷貝。


func main() {
    jim := person{10,"Jim"}
    fmt.Println(jim)
    modify(jim)
    fmt.Println(jim)
}

func modify(p person) {
    p.age =p.age+10
}

type person struct {
    age int
    name string
}


以上示例的輸出是一樣的,所以我們可以驗(yàn)證傳遞的是值的副本。如果上面的例子我們要修改age的值可以通過(guò)傳遞結(jié)構(gòu)體的指針,我們稍微改動(dòng)下例子:


func main() {
    jim := person{10,"Jim"}
    fmt.Println(jim)
    modify(&jim)
    fmt.Println(jim)
}

func modify(p *person) {
    p.age =p.age+10
}

type person struct {
    age int
    name string
}


這個(gè)例子的輸出是:


{10 Jim}
{20 Jim}


非常明顯的,age的值已經(jīng)被改變。如果結(jié)構(gòu)體里有引用類型的值,比如map,那么即使我們傳遞的是結(jié)構(gòu)體的值副本,如果修改這個(gè)map的話,原結(jié)構(gòu)的對(duì)應(yīng)的map值也會(huì)被修改。這里不再寫(xiě)例子,大家可以驗(yàn)證下。


自定義類型


Go語(yǔ)言支持我們自定義類型,比如剛剛上面的結(jié)構(gòu)體類型,就是我們自定義的類型,這也是比較常用的自定義類型的方法。


另外一個(gè)自定義類型的方法是基于一個(gè)已有的類型,就是基于一個(gè)現(xiàn)有的類型創(chuàng)造新的類型,這種也是使用type關(guān)鍵字。


type Duration int64


我們?cè)谑褂?code>time這個(gè)包的時(shí)候,對(duì)于類型time.Duration應(yīng)該非常熟悉,它其實(shí)就是基于int64 這個(gè)基本類型創(chuàng)建的新類型來(lái)表示時(shí)間的間隔。


但是這里我們注意,雖然Duration是基于int64創(chuàng)建的,覺(jué)得它們其實(shí)一樣,比如都可以使用數(shù)字賦值。


type Duration int64

var i Duration = 100
var j int64 = 100


但是本質(zhì)上,它們并不是同一種類型,所以對(duì)于Go這種強(qiáng)類型語(yǔ)言,它們是不能相互賦值的。


type Duration int64

var dur Duration
dur=int64(100)
fmt.Println(dur)


上面的例子,在編譯的時(shí)候,會(huì)報(bào)類型轉(zhuǎn)換的異常錯(cuò)誤。


cannot use int64(100) (type int64) as type Duration in assignment


Go的編譯器不會(huì)像Java的那樣,幫我們做隱式的類型轉(zhuǎn)換。


有時(shí)候,大家會(huì)迷茫,已經(jīng)有了int64這些類型了,可以表示,還要基于它們創(chuàng)建新的類型做什么?其實(shí)這就是Go靈活的地方,我們可以使用自定義的類型做很多事情,比如添加方法,比如可以更明確的表示業(yè)務(wù)的含義等


當(dāng)前標(biāo)題:Go語(yǔ)言之類型
瀏覽地址:http://weahome.cn/article/iegppc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部