您好,登錄后才能下訂單哦!
序:
在Java語言中,存在兩套完全獨立的類型系統:一套是值類型系統,主要是基本類型,如byte int boolean char double等,這些類型基于值語義;一套是以object類型為根的對象類型系統,這些類型可以定義成員變量和成員方法,可以有虛函數,基于引用語義,只允許在堆上創建(通過使用關鍵字new)。Java語言中的Any類型就是整個對象系統的根——java.lang.Object類型,只有對象類型系統中的實例才可以被Any類型引用。值類型想要被Any類型引用,需要裝箱(boxing)過程,比如int類型需要裝箱成為Integer類型。另外,只有對象類型系統中的類型才可以實現接口,具體方法是讓該類型從要實現的接口繼承。
相比之下,Go語言中的大多數類型都是值語義,并且都可以包含對應的操作方法。在需要的時候,你可以給任何類型(包括內置類型)"增加"新方法。而在實現某個接口時,無需從該接口集成(事實上,GO語言根本就不支持面向對象思想中的繼承語法),只需要實現該接口要求的所有方法即可。任何類型都可以被Any類型引用。Any類型就是空接口,即interface()。
為類型添加方法:
在GO語言中,你可以給任意類型(包括內置類型,但不包括指針類型)添加相應的方法,例如:
type Integer int
func (a Integer) Less (b Integer) bool {
return a < b
}
在這個例子中,我們定義了一個新類型Integer,它和int沒有本質不同,只是它為內置的int類型增加了個新方法Less()。
這樣實現了Integer后,就可以讓整型像一個普通類一樣使用:
func main() {
var a Integer = 1
if a.Less(2) {
fmt.Println(a, "Less 2")
}
}
值語義和引用語義:
值語義和引用語義的差別在于賦值,比如下面的例子:
b = a
b.Modify()
如果b的修改不會影響a的值,那么此類型屬于值類型。如果會影響a的值,那么此類型是引用類型。
GO語言中大多數類型都基于值語義,包括:
基本類型,如byte int bool float32 float64 和 string 等
復合類型,如數組(array) 結構體(struct) 和指針(pointer) 等
GO語言中類型的值語義表現的非常徹底。之所以這么說,是因為數組。
GO語言中的數組和基本類型沒有區別,是很純粹的值類型,例如:
var a = [3]int{1,2,3}
var b = a
b[1]++
fmt.Println(a, b)
該程序的運行結果如下:
[1 2 3] [1 3 3]
這表明b=a賦值語句是數組內容的完整復制。要想表達引用,需要用指針:
var a = [3]int{1, 2, 3}
var b = &a
b[1]++
fmt.Println(a, *b)
該程序的運行結果如下:
[1 3 3] [1 3 3]
這表明b=&a賦值語句是數組內容的引用。變量b的類型不是[3]int,而是*[3]int類型。
GO語言中4個類型比較特別,看起來像引用類型,如下所示。
數組切片:指向數組(array)的一個區間。
map:極其常見的數據結構,提供鍵值查詢能力。
channel:執行體(goroutine)間的通信設施。
接口(interface):對一組滿足某個契約的類型的抽象。
但是這并不影響我們將GO語言類型看做值語義。下面我們來看看這4個類型。
數組切片本質上是一個區間,你可以大致將[]T表示為:
type slice struct {
first *T
len int
cap int
}
因為數組切片是指向數組的指針,所以可以改變所指向的數組元素并不奇怪。數組切片類型本身的賦值仍然是值語義。
結構體:
GO語言的結構體(struct)和其他語言的類(class)有同等的地位,但Go語言放棄了包括集成在內的大量面向對象特性,只保留了組合(composition)這個最基礎的特性。
上面我們說到,所有的Go語言類型(指針類型除外)都可以有自己的方法。在這個背景下,Go語言的結構體只是很普通的復合類型,平淡無奇。例如,我們要定義一個矩形類型:
type Rect struct {
x, y float64
width, height float64
}
然后我們定義成員方法Area()來計算矩形的面積:
func (r *Rect) Area() float64 {
return r.width * r.height
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。