把存貨趕忙更新一波(捂臉)golang
1. 類型系統shell
類型系統,就是說一種編程語言怎麼設計的它的類型的體系結構。編程
好比基礎類型啊,複合類型啊,一些能夠指向任意對象的類型啊,以及類型的語義,面向對象的特性,接口,這些內容。編程語言
2. 類型的方法函數
在Golang裏,能夠給任意類型添加方法。this
好比:spa
type Integer int func (i Integer)Less (b Integer) bool { return a<b }
Integer與int沒有本質的不一樣。咱們聲明瞭一個屬於Integer的函數Less()。這樣咱們就能夠把整型看成普通的類來使用:設計
func main() { var a Integer = 1 if a.Less(2) { fmt.Println(a, "Less 2") } }
那麼類型的方法究竟是什麼呢?咱們把剛纔的Less()和下面的方法作個對比:指針
func NewLess(a Integer, b Integer) bool { return a<b }
這裏,我刻意沒有把a和b寫在一塊兒。對比剛纔的Less()方法,咱們發現,所謂的類型方法,關鍵在於隱藏的this指針。若是咱們把類型a放到傳遞參數的部分,咱們就發現這兩個函數並無區別。code
若是咱們須要在類型方法中對類型的實例自己進行修改,那麼在聲明的時候,就須要聲明成指針。這也很好理解,就跟傳遞參數的時候傳遞指針是同樣的道理。
func (i *Integer)Less (b Integer) bool { return a<b }
關於成員函數,再加一個例子
type T struct { num int } func (t T) add1() { t.num += 5 } func (t *T) add2() { t.num += 5 } func main() { t1 := T{5} t2 := &T{5} fmt.Println(t1) fmt.Println(t2) t1.add1() fmt.Println(t1.num) t1.add2() fmt.Println(t1.num) t2.add1() fmt.Println(t2.num) t2.add2() fmt.Println(t2.num) }
其結果以下:
shell> go run main.go {5} &{5} 5 10 5 10
3. 值語義和引用語義
值語義和引用語義的區別主要在於賦值。
b = a
b.Modify()
若是此時a沒有變化,就是值類型,反之是引用類型。
Golang中大部分類型都是值類型。
因此只要記住引用類型便可。他們是切片,map,channel和接口。
4. 結構體和結構體的初始化
結構體struct跟其餘語言的struct和class差很少。不過golang沒有傳統意義上的繼承。
type Rect struct { x, y float64 width, height float64 }
struct的實例的初始化方法以下:
rect1 := new(Rect) rect2 := Rect{} rect3 := Rect{0, 0, 100, 200} rect4 := Rect{width: 100, height: 200}
須要注意的是,沒有顯式初始化的成員都會初始化爲該類型的0值。
另外golang中沒有構造函數的概念。若是須要相似的構造函數,一般是建立一個全局函數進行新對象的建立。
5. 結構體的組合
前面提到golang並無傳統意義上的繼承,可是,golang提供了組合。
type Base struct { Name string } func (base *Base) Foo() {...} func (base *Base) Bar() {...} type Foo struct { Base ... } func (foo *Foo) Bar() { foo.Base.Bar() ... }
能夠看到,上面的代碼定義了一個Base類,實現了Foo()和Bar()兩個方法。而後定義了一個Foo類,該類中組合了Base類。
從形式了,Foo類「繼承」了Base類,並改寫了Bar()方法,同時在Bar()方法中調用了Base基類中的Bar()方法。
對於沒有被改寫的方法,就至關因而被「繼承」了,同時仍然能夠經過組合的類型來訪問方法。好比,foo.Foo()和foo.Base.Foo()的效果是一致的。
6. 可見性
跟前面提到的相同,golang使用首字母大小寫區別public和private。
7. 接口
Golang中的接口是非入侵式的。一個類只要實現了接口要求的全部函數,這個類就實現了該接口。
未完待續