1. 程式人生 > 實用技巧 >Go型別系統概述

Go型別系統概述

概念:基本型別(basic type)

內建基本型別已經在前面的文章基本型別和它們的字面量表示一文中介紹過了。 為了本文的完整性,這些內建型別重新被列在這裡:
  • 內建字串型別:string.
  • 內建布林型別:bool.
  • 內建數值型別:
    • int8uint8byte)、int16uint16int32rune)、uint32int64uint64intuintuintptr
    • float32float64
    • complex64complex128

注意,byteuint8的一個內建別名,runeint32的一個內建別名。 下面將要提到如何宣告自定義的類型別名。

除了

字串型別,《Go語言101》後續其它文章將不再對其它基本型別做詳細講解。

概念:組合型別(composite type)

Go支援下列組合型別:
  • 指標型別- 類C指標
  • 結構體型別- 類C結構體
  • 函式型別- 函式型別在Go中是一種一等公民類別
  • 容器型別,包括:
    • 陣列型別 - 定長容器型別
    • 切片型別 - 動態長度和容量容器型別
    • 對映型別(map)- 也常稱為字典型別。在標準編譯器中對映是使用雜湊表實現的。
  • 通道型別- 通道用來同步併發的協程
  • 介面型別- 介面在反射和多型中發揮著重要角色
非定義組合型別可以用它們各自的字面表示形式來表示。 下面是一些各種不同種類的非定義組合型別字面表示形式的例子(非定義型別將在下面解釋):
//
假設T為任意一個型別,Tkey為一個支援比較的型別。 *T // 一個指標型別 [5]T // 一個元素型別為T、元素個數為5的陣列型別 []T // 一個元素型別為T的切片型別 map[Tkey]T // 一個鍵值型別為Tkey、元素型別為T的對映型別 // 一個結構體型別 struct { name string age int } // 一個函式型別 func(int) (bool, string) // 一個介面型別 interface { Method0(string) int Method1() (int, bool) }
// 幾個通道型別 chan T chan<- T <-chan T

語法:型別定義(type definition declaration)

型別定義又稱型別定義宣告。在Go 1.9之前,型別定義被稱為型別宣告並且是唯一的一種型別宣告形式。 但是自從Go 1.9,型別定義變成了兩種型別宣告形式之一。另一種新的型別宣告形式為下一節將要介紹的類型別名宣告。)

在Go中,我們可以用如下形式來定義新的型別。在此語法中,type為一個關鍵字。
// 定義單個型別。
type NewTypeName SourceType

// 定義多個型別。
type (
    NewTypeName1 SourceType1
    NewTypeName2 SourceType2
)

的型別名必須為識別符號。但是請注意:包級型別(以及下一節將要介紹的類型別名)的名稱不能為init

上例中的第二個型別宣告中包含兩個型別描述(type specification)。 如果一個型別宣告包含多於一個的型別描述,這些型別描述必須用一對小括號()括起來。

注意:
  • 一個新定義的型別和它的源型別為兩個不同的型別。
  • 在兩個不同的型別定義中的定義的兩個型別肯定為兩個不同的型別。
  • 一個新定義的型別和它的源型別的底層型別(將在下面介紹)一致並且它們的值可以相互顯式轉換。
  • 型別定義可以出現在函式體內。

一些型別定義的例子:

// 下面這些新定義的型別和它們的源型別都是基本型別。
type (
	MyInt int
	Age   int
	Text  string
)

// 下面這些新定義的型別和它們的源型別都是組合型別。
type IntPtr *int
type Book struct{author, title string; pages int}
type Convert func(in0 int, in1 bool)(out0 int, out1 string)
type StringArray [5]string
type StringSlice []string

func f() {
	// 這三個新定義的型別名稱只能在此函式內使用。
	type PersonAge map[string]int
	type MessageQueue chan string
	type Reader interface{Read([]byte) int}
}

  

語法:類型別名宣告(type alias declaration)

類型別名宣告是一種在Go 1.9中新增的型別宣告形式。)

上面已經提到了,Go中有兩個內建類型別名:byte(型別uint8的別名)和rune(型別int32的別名)。 在Go 1.9之前,它們是Go中僅有的兩個類型別名。

從Go 1.9開始,我們可以使用下面的語法來宣告自定義類型別名。此語法和型別定義類似,但是請注意其中多了一個等號=
type (
    Name = string
    Age  = int
)

type table = map[string]int
type Table = map[Name]Age