新聞中心
序:
在Java語(yǔ)言中,存在兩套完全獨(dú)立的類(lèi)型系統(tǒng):一套是值類(lèi)型系統(tǒng),主要是基本類(lèi)型,如byte int boolean char double等,這些類(lèi)型基于值語(yǔ)義;一套是以object類(lèi)型為根的對(duì)象類(lèi)型系統(tǒng),這些類(lèi)型可以定義成員變量和成員方法,可以有虛函數(shù),基于引用語(yǔ)義,只允許在堆上創(chuàng)建(通過(guò)使用關(guān)鍵字new)。Java語(yǔ)言中的Any類(lèi)型就是整個(gè)對(duì)象系統(tǒng)的根——java.lang.Object類(lèi)型,只有對(duì)象類(lèi)型系統(tǒng)中的實(shí)例才可以被Any類(lèi)型引用。值類(lèi)型想要被Any類(lèi)型引用,需要裝箱(boxing)過(guò)程,比如int類(lèi)型需要裝箱成為Integer類(lèi)型。另外,只有對(duì)象類(lèi)型系統(tǒng)中的類(lèi)型才可以實(shí)現(xiàn)接口,具體方法是讓該類(lèi)型從要實(shí)現(xiàn)的接口繼承。
相比之下,Go語(yǔ)言中的大多數(shù)類(lèi)型都是值語(yǔ)義,并且都可以包含對(duì)應(yīng)的操作方法。在需要的時(shí)候,你可以給任何類(lèi)型(包括內(nèi)置類(lèi)型)"增加"新方法。而在實(shí)現(xiàn)某個(gè)接口時(shí),無(wú)需從該接口集成(事實(shí)上,GO語(yǔ)言根本就不支持面向?qū)ο笏枷胫械睦^承語(yǔ)法),只需要實(shí)現(xiàn)該接口要求的所有方法即可。任何類(lèi)型都可以被Any類(lèi)型引用。Any類(lèi)型就是空接口,即interface()。
為類(lèi)型添加方法:
在GO語(yǔ)言中,你可以給任意類(lèi)型(包括內(nèi)置類(lèi)型,但不包括指針類(lèi)型)添加相應(yīng)的方法,例如:
type Integer int
func (a Integer) Less (b Integer) bool {
return a < b
}
在這個(gè)例子中,我們定義了一個(gè)新類(lèi)型Integer,它和int沒(méi)有本質(zhì)不同,只是它為內(nèi)置的int類(lèi)型增加了個(gè)新方法Less()。
這樣實(shí)現(xiàn)了Integer后,就可以讓整型像一個(gè)普通類(lèi)一樣使用:
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的值,那么此類(lèi)型屬于值類(lèi)型。如果會(huì)影響a的值,那么此類(lèi)型是引用類(lèi)型。
GO語(yǔ)言中大多數(shù)類(lèi)型都基于值語(yǔ)義,包括:
基本類(lèi)型,如byte int bool float32 float64 和 string 等
復(fù)合類(lèi)型,如數(shù)組(array) 結(jié)構(gòu)體(struct) 和指針(pointer) 等
GO語(yǔ)言中類(lèi)型的值語(yǔ)義表現(xiàn)的非常徹底。之所以這么說(shuō),是因?yàn)閿?shù)組。
GO語(yǔ)言中的數(shù)組和基本類(lèi)型沒(méi)有區(qū)別,是很純粹的值類(lèi)型,例如:
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的類(lèi)型不是[3]int,而是*[3]int類(lèi)型。
GO語(yǔ)言中4個(gè)類(lèi)型比較特別,看起來(lái)像引用類(lèi)型,如下所示。
數(shù)組切片:指向數(shù)組(array)的一個(gè)區(qū)間。
map:極其常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),提供鍵值查詢能力。
channel:執(zhí)行體(goroutine)間的通信設(shè)施。
接口(interface):對(duì)一組滿足某個(gè)契約的類(lèi)型的抽象。
但是這并不影響我們將GO語(yǔ)言類(lèi)型看做值語(yǔ)義。下面我們來(lái)看看這4個(gè)類(lèi)型。
數(shù)組切片本質(zhì)上是一個(gè)區(qū)間,你可以大致將[]T表示為:
type slice struct {
first *T
len int
cap int
}
因?yàn)閿?shù)組切片是指向數(shù)組的指針,所以可以改變所指向的數(shù)組元素并不奇怪。數(shù)組切片類(lèi)型本身的賦值仍然是值語(yǔ)義。
結(jié)構(gòu)體:
GO語(yǔ)言的結(jié)構(gòu)體(struct)和其他語(yǔ)言的類(lèi)(class)有同等的地位,但Go語(yǔ)言放棄了包括集成在內(nèi)的大量面向?qū)ο筇匦裕槐A袅私M合(composition)這個(gè)最基礎(chǔ)的特性。
上面我們說(shuō)到,所有的Go語(yǔ)言類(lèi)型(指針類(lèi)型除外)都可以有自己的方法。在這個(gè)背景下,Go語(yǔ)言的結(jié)構(gòu)體只是很普通的復(fù)合類(lèi)型,平淡無(wú)奇。例如,我們要定義一個(gè)矩形類(lèi)型:
type Rect struct {
x, y float64
width, height float64
}
然后我們定義成員方法Area()來(lái)計(jì)算矩形的面積:
func (r *Rect) Area() float64 {
return r.width * r.height
}
創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
網(wǎng)站名稱:golang中的類(lèi)型系統(tǒng)-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://www.dlmjj.cn/article/iessd.html