03Go 類型總結

Go 類型總結

[TOC]數組

一、內置類型和內置函數

內置類型:

類型 ⻓度 默認值 說明
bool 1 false 布爾型只有true和false
byte 1 0 uint8的別名
rune 4 0 Unicode Code Point, int32別名
int, uint 4 或 8 0 有符號和無符號證書,根據系統可能32 或 64 位
int8, uint8 1 0 -128 ~ 127, 0 ~ 255
int16, uint16 2 0 -32768 ~ 32767, 0 ~ 65535
int32, uint32 4 0 -21億 ~ 21 億, 0 ~ 42 億
int64, uint64 8 0
float32 4 0.0 單精度浮點型 ,小數位:精確到7小數位
float64 8 0.0 雙精度浮點型,小數位:精確到15小數位
complex64 8 負數
complex128 16
uintptr 4 或 8 nil ⾜以存儲指針的 uint32 或 uint64 整數
array 數組,值類型
struct 結構體,值類型
string "" UTF-8 字符串
slice nil 引⽤類型
map nil 引⽤類型
channel nil 引⽤類型
interface nil 接⼝
function nil 函數
error nil 錯誤

內置函數:不須要導入就能使用的函數 (瞭解便可)

函數 說明
append 追加元素到slice,返回修改後的slice
close 用來關閉channel
delete 從map中刪除key對應的value
panic 用來作錯誤處理 panic和rcover
recover 容許程序定義goroutine的panic動做
imag 返回complex的實部,(complex,real imag:操做複數)
real 返回complex的虛部
make 用來分配內存,返回Type自己(只應用於slice,map,channel)
new 用來分配內存,主要用來分配值類型。返回指向Type的指針
cap 用於求最大容量,好比array,slice,channel,返回最大容量
copy 用於賦值和鏈接slice,返回複製的數目
len 返回長度
print、println 底層打印函數,通常用fmt包的打印

二、類型轉換

  • Go中不存在隱式轉換,全部類型轉換必須顯式聲明
  • 轉換隻能發生在兩種相互兼容的類型之間
  • int(a) 類型(被轉換變量)

三、變量

Go語言是靜態類型語言,不能在運行期間改變變量類型。使用關鍵字 var 定義變量,自動初始化爲零值。若是提供初始化值,可省略變量類型,由編譯器自動推斷。app

(1)單個變量聲明

var x int                    //使用var
var s = "abc"                //省略類型
s:="abc"                    //函數內部能夠省略var

(2)多個變量聲明

var x, y, z int                //定義多個
var s, n = "abc", 123        //定義多個省略類型
var (                        //多個,多類型
    a int
    b float32
)
//在函數內部,可⽤更簡略的 ":=" ⽅式定義變量
a,b:=128,"12"

(3)多變量賦值時,先計算全部相關值,而後再從左到右依次賦值

data, i := [3]int{0, 1, 2}, 0
i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100)

(4)編譯器會將未使⽤的局部變量當作錯誤

(5)注意從新賦值與定義新同名變量的區別。

​ 同一代碼塊,從新賦值內存地址不變。不一樣代碼塊定義同名變量,內存地址不一樣。函數

(6)全局變量、局部變量、形參 以及優先級

四、常量

常量值必須是編譯期可肯定的數字(整型、浮點型、複數)、字符串、布爾值ui

(1)單個常量聲明

const s string = "Hello, World!"
const s="Hello, World!"

(2)多個常量定義

const x, y int = 1, 2 // 多常量初始化
const (             // 常量組
    a, b = 10, 100
    c bool = false
)

(3)在常量組中,如不提供類型和初始化值,那麼視做與上⼀常量相同。

const (
    s = "abc"
    x                 // x = "abc"
)

(4)常量值還能夠是 len、 cap、 unsafe.Sizeof 等編譯期可肯定結果的函數返回值

const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(b)
)

(5)未使用的局部常量不會引起編譯錯誤

(6)枚舉:關鍵字 iota 定義常量組中從 0 開始按⾏計數的⾃增枚舉值。

  • 從 0 開始按⾏計數的自增
  • 在同⼀常量組中,能夠提供多個 iota,它們各⾃增⻓。
  • 若是 iota ⾃增被打斷,須顯式恢復。
const (
    _ = iota     // iota = 0
    KB int64 = 1 << (10 * iota) // iota = 1
    MB             // 與 KB 表達式相同,但 iota = 2
)
const (            //在同⼀常量組中,能夠提供多個 iota,它們各⾃增⻓。
    A, B = iota, iota << 10 // 0, 0 << 10
    C, D         // 1, 1 << 10
)
//若是 iota ⾃增被打斷,須顯式恢復。
const (
    A = iota // 0
    B // 1
    C = "c" // c
    D // c,與上⼀⾏相同。
    E = iota // 4,顯式恢復。注意計數包含了 C、 D 兩⾏。
    F // 5
)

五、指針

Go語言支持指針類型*T,指針的指針**T,以及包含包名前綴的*package.T指針

  • 操做符 "&" 取變量地址, "*" 透過指針訪問目標對象。
  • 默認值 nil,沒有 NULL 常量。
  • 不⽀持指針運算,不⽀持 "->" 運算符,直接⽤ "." 訪問目標成員。

指針聲明

var ip *int         //聲明一個int值的指針變量
var sp *string        //生成string值的指針變量
var str="hello"
sp:= &str            //:=定義指針
var p **int            //聲明指針的指針

類型轉換:go語言指針是不容許指針類型轉換的。可是unsafe.Pointer能夠變相實現運算

unsafe.Pointer類型用於表示任意類型的指針。有4個特殊的只能用於Pointer類型的操做:code

一、 任意類型的指針能夠轉換爲一個Pointer類型值
二、 一個Pointer類型值能夠轉換爲任意類型的指針
三、 一個uintptr類型值能夠轉換爲一個Pointer類型值
四、 一個Pointer類型值能夠轉換爲一個uintptr類型值對象

func main() {
    d := struct {
    s string
    x int
}{"abc", 100}
    p := uintptr(unsafe.Pointer(&d)) // *struct -> Pointer -> uintptr
    p += unsafe.Offsetof(d.x)         // uintptr + offset
    p2 := unsafe.Pointer(p)         // uintptr -> Pointer
    px := (*int)(p2)                 // Pointer -> *int
    *px = 200                         // d.x = 200
    fmt.Printf("%#v\n", d)
}
//輸出:
struct { s string; x int }{s:"abc", x:200}

注意: GC 把 uintptr 當成普通整數對象,它⽆法阻⽌ "關聯" 對象被回收。索引

六、字符串

字符串是不可變的值類型,內部用指針指向UTF-8字節數組。ip

在Go語言中,沒有字符類型,字符類型是rune類型,rune是int32的別稱。可以使用 []byte() 獲取字節,使用 []rune() 獲取字符,可對中文進行轉換。內存

  • 默認值是空字符串 ""。
  • ⽤索引號訪問某字節,如 s[i]。
  • 不能⽤序號獲取字節元素指針, &s[i] ⾮法。
  • 不可變類型,⽆法修改字節數組。
  • 字節數組尾部不包含 NULL。

(1)定義字符串

//「abc」 雙引號定義字符串 ``  反引號定義非轉義字符串,多行
str := `aaaa
            能夠跨行`
str:="abc"

(2)+號鏈接字符串:,"+" 必須在上一行末尾,不然致使編譯錯誤。鏈接是會產生新的字符串。

​ 固然還有函數鏈接,這個放到字符串專題總結。如fmt.Sprintf() 等

(3)單引號字符常量

​ 單引號字符常量表⽰ Unicode Code Point,⽀持 uFFFF、 U7FFFFFFF、 xFF 格式。對應 rune 類型, UCS-4。

func main() {
    fmt.Printf("%T\n", 'a')
    var c1, c2 rune = '\u6211', '們'
    println(c1 == '我', string(c2) == "\xe4\xbb\xac")
}
//輸出:
int32 // rune 是 int32 的別名
true true

(4)修改字符串

要修改字符串,可先將其轉換成 []rune 或 []byte,完成後再轉換爲 string。⽆論哪一種轉換,都會從新分配內存,並複製字節數組。

七、自定義類型和類型別名

可將類型分爲命名和未命名兩⼤類。命名類型包括 bool、 int、 string 等,⽽ array、slice、 map 等和具體元素類型、⻓度等有關,屬於未命名類型。
具備相同聲明的未命名類型被視爲同⼀類型。

  • 具備相同基類型的指針
  • 具備相同元素類型和⻓度的 array。
  • 具備相同元素類型的 slice。
  • 具備相同鍵值類型的 map。
  • 具備相同元素類型和傳送⽅向的 channel。
  • 具備相同字段序列 (字段名、類型、標籤、順序) 的匿名 struct。
  • 簽名相同 (參數和返回值,不包括參數名稱) 的 function。
  • ⽅法集相同 (⽅法名、⽅法簽名相同,和次序⽆關) 的 interface。

使用type關鍵字自定義類型:

//可⽤ type 在全局或函數內定義新類型。
func main() {
    type bigint int64
    var x bigint = 100
    println(x)
}

注意:新類型不是原類型的別名,除擁有相同數據存儲結構外,它們之間沒有任何關係,不會持有原類型任何信息。除⾮目標類型是未命名類型,不然必須顯式轉換。

相關文章
相關標籤/搜索