溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

golang中的類型系統(tǒng)

發(fā)布時(shí)間:2020-10-16 10:25:41 來(lái)源:網(wǎng)絡(luò) 閱讀:1162 作者:yeleven 欄目:編程語(yǔ)言

序:

在Java語(yǔ)言中,存在兩套完全獨(dú)立的類型系統(tǒng):一套是值類型系統(tǒng),主要是基本類型,如byte int boolean char double等,這些類型基于值語(yǔ)義;一套是以object類型為根的對(duì)象類型系統(tǒng),這些類型可以定義成員變量和成員方法,可以有虛函數(shù),基于引用語(yǔ)義,只允許在堆上創(chuàng)建(通過(guò)使用關(guān)鍵字new)。Java語(yǔ)言中的Any類型就是整個(gè)對(duì)象系統(tǒng)的根——java.lang.Object類型,只有對(duì)象類型系統(tǒng)中的實(shí)例才可以被Any類型引用。值類型想要被Any類型引用,需要裝箱(boxing)過(guò)程,比如int類型需要裝箱成為Integer類型。另外,只有對(duì)象類型系統(tǒng)中的類型才可以實(shí)現(xiàn)接口,具體方法是讓該類型從要實(shí)現(xiàn)的接口繼承。

相比之下,Go語(yǔ)言中的大多數(shù)類型都是值語(yǔ)義,并且都可以包含對(duì)應(yīng)的操作方法。在需要的時(shí)候,你可以給任何類型(包括內(nèi)置類型)"增加"新方法。而在實(shí)現(xiàn)某個(gè)接口時(shí),無(wú)需從該接口集成(事實(shí)上,GO語(yǔ)言根本就不支持面向?qū)ο笏枷胫械睦^承語(yǔ)法),只需要實(shí)現(xiàn)該接口要求的所有方法即可。任何類型都可以被Any類型引用。Any類型就是空接口,即interface()。


為類型添加方法:

在GO語(yǔ)言中,你可以給任意類型(包括內(nèi)置類型,但不包括指針類型)添加相應(yīng)的方法,例如:

type Integer int

func (a Integer) Less (b Integer) bool {

    return a < b

}

在這個(gè)例子中,我們定義了一個(gè)新類型Integer,它和int沒(méi)有本質(zhì)不同,只是它為內(nèi)置的int類型增加了個(gè)新方法Less()。

這樣實(shí)現(xiàn)了Integer后,就可以讓整型像一個(gè)普通類一樣使用:

func main() {

    var a Integer = 1

    if a.Less(2) {

        fmt.Println(a, "Less 2")

    }

}


值語(yǔ)義和引用語(yǔ)義:

值語(yǔ)義和引用語(yǔ)義的差別在于賦值,比如下面的例子:

b = a

b.Modify()

如果b的修改不會(huì)影響a的值,那么此類型屬于值類型。如果會(huì)影響a的值,那么此類型是引用類型。

GO語(yǔ)言中大多數(shù)類型都基于值語(yǔ)義,包括:

基本類型,如byte int bool float32 float64 和 string 等

復(fù)合類型,如數(shù)組(array) 結(jié)構(gòu)體(struct) 和指針(pointer) 等

GO語(yǔ)言中類型的值語(yǔ)義表現(xiàn)的非常徹底。之所以這么說(shuō),是因?yàn)閿?shù)組。

GO語(yǔ)言中的數(shù)組和基本類型沒(méi)有區(qū)別,是很純粹的值類型,例如:

var a = [3]int{1,2,3}

var b = a

b[1]++

fmt.Println(a, b)

該程序的運(yùn)行結(jié)果如下:

[1 2 3] [1 3 3]

這表明b=a賦值語(yǔ)句是數(shù)組內(nèi)容的完整復(fù)制。要想表達(dá)引用,需要用指針:

var a = [3]int{1, 2, 3}

var b = &a

b[1]++

fmt.Println(a, *b)

該程序的運(yùn)行結(jié)果如下:

[1 3 3] [1 3 3]

這表明b=&a賦值語(yǔ)句是數(shù)組內(nèi)容的引用。變量b的類型不是[3]int,而是*[3]int類型。

GO語(yǔ)言中4個(gè)類型比較特別,看起來(lái)像引用類型,如下所示。

數(shù)組切片:指向數(shù)組(array)的一個(gè)區(qū)間。

map:極其常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),提供鍵值查詢能力。

channel:執(zhí)行體(goroutine)間的通信設(shè)施。

接口(interface):對(duì)一組滿足某個(gè)契約的類型的抽象。

但是這并不影響我們將GO語(yǔ)言類型看做值語(yǔ)義。下面我們來(lái)看看這4個(gè)類型。

數(shù)組切片本質(zhì)上是一個(gè)區(qū)間,你可以大致將[]T表示為:

type slice struct {

    first *T

    len int

    cap int

}

因?yàn)閿?shù)組切片是指向數(shù)組的指針,所以可以改變所指向的數(shù)組元素并不奇怪。數(shù)組切片類型本身的賦值仍然是值語(yǔ)義。


結(jié)構(gòu)體:

GO語(yǔ)言的結(jié)構(gòu)體(struct)和其他語(yǔ)言的類(class)有同等的地位,但Go語(yǔ)言放棄了包括集成在內(nèi)的大量面向?qū)ο筇匦裕槐A袅私M合(composition)這個(gè)最基礎(chǔ)的特性。

上面我們說(shuō)到,所有的Go語(yǔ)言類型(指針類型除外)都可以有自己的方法。在這個(gè)背景下,Go語(yǔ)言的結(jié)構(gòu)體只是很普通的復(fù)合類型,平淡無(wú)奇。例如,我們要定義一個(gè)矩形類型:

type Rect struct {

    x, y float64

    width, height float64

}

然后我們定義成員方法Area()來(lái)計(jì)算矩形的面積:

func (r *Rect) Area() float64 {

    return r.width * r.height

}




向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI