第 1 章 類型介紹

1.1 變量

Go 是靜態(tài)類型語?逐纬,不能在運(yùn)?期改變變量類型蛔屹。

使?關(guān)鍵字 var 定義變量,?動(dòng)初始化為零值豁生。如果提供初始化值兔毒,可省略變量類型,由編譯器?動(dòng)推斷甸箱。

var a int

var f float32 = 1.6

var s = "abc" ?//編譯器自動(dòng)推導(dǎo)類型

在函數(shù)內(nèi)部育叁,可?更簡略的 ":=" ?式定義變量,自動(dòng)推導(dǎo)類型摇肌。

func main() {

x := 66 ?// 注意檢查擂红,是定義新局部變量仪际,還是修改全局變量围小。該?式容易造成錯(cuò)誤。

//x:=22 ?//在一個(gè)main函數(shù)里定義過的類型树碱,不能再使用這種方式

}

可?次定義多個(gè)變量肯适。

var x, y, z int

var s, n = "abc", 123

var (

a int

b float32

)

func main() {

n, s := 0x1234, "Hello, World!"

println(x, s, n) ?//打印時(shí)自動(dòng)換行

}

多變量賦值時(shí),先計(jì)算所有相關(guān)值成榜,然后再從左到右依次賦值框舔。

data, i := [3]int{0, 1, 2}, 0

i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100)

?_ ?實(shí)際上是一個(gè)只寫變量,你不能得到它的值,不能讀赎婚,?于忽略值刘绣,占位


func test() (int, string) {

return 1, "abc"

}

func main() {

_,s := test() ? //接受一個(gè)返回值挣输,忽略一個(gè)

println(s)

}

編譯器會(huì)將未使?的局部變量當(dāng)做錯(cuò)誤纬凤。

import(

"fmt" ?//導(dǎo)入一個(gè)輸入輸出的包,

_"fmt" ?//如果不使用撩嚼,可以前面加上 _ ?,不然編譯器會(huì)報(bào)錯(cuò)

)

var s string // 全局變量沒問題停士。

func main() {

i := 0 // Error: i declared and not used挖帘。 (可使? "_ = i" 規(guī)避)

}

注意重新賦值與定義新同名變量的區(qū)別。

s := "abc"

println(&s)

s, y := "hello", 20 // 重新賦值: 與前 s 在同?層次的代碼塊中恋技,且有新的變量被定義拇舀。

println(&s, y) // 通常函數(shù)多返回值 err 會(huì)被重復(fù)使?。

{

s, z := 1000, 30 // 定義新同名變量: 不在同?層次代碼塊蜻底。

println(&s, z)

}

輸出:

0x2210230f30

0x2210230f30 20

0x2210230f18 30




1.2 常量

常量值必須是編譯期可確定的數(shù)字骄崩、字符串、布爾值薄辅。

const x, y int = 1, 2 // 多常量初始化

const s = "Hello, World!" // 類型推斷

const ( // 常量組

a, b = 10, 100

c bool = false


)

func main() {

const x = "xxx" // 未使?局部常量不會(huì)引發(fā)編譯錯(cuò)誤刁赖。

}

不?持 1UL、 2LL 這樣的類型后綴长搀。

在常量組中宇弛,如不提供類型和初始化值,那么視作與上?常量相同源请。

const (

s = "abc"

x // x = "abc"

)

常量值還可以是 len枪芒、 cap、 unsafe.Sizeof 等編譯期可確定結(jié)果的函數(shù)返回值谁尸,

不能將函數(shù)的返回值賦給常量舅踪,因?yàn)楹瘮?shù)調(diào)用發(fā)生在運(yùn)行期

const (

a = "abc"

b = len(a)

c = unsafe.Sizeof(b)

)

如果常量類型?以存儲(chǔ)初始化值,那么不會(huì)引發(fā)溢出錯(cuò)誤良蛮。

const (

a byte = 100 // int to byte

b int = 1e20 // float64 to int, overflows

)

枚舉

關(guān)鍵字 iota 定義常量組中從 0 開始按?計(jì)數(shù)的?增枚舉值抽碌。

const (

Sunday = iota // 0

Monday // 1,通常省略后續(xù)?表達(dá)式决瞳。

Tuesday // 2

Wednesday // 3

Thursday // 4

Friday // 5

Saturday // 6

)


const (

_ = iota // iota = 0

KB int64 = 1 << (10 * iota) // iota = 1

MB // 與 KB 表達(dá)式相同货徙,但 iota = 2

GB

TB

)

在同?常量組中,可以提供多個(gè) iota皮胡,它們各?增?痴颊。

const (

A, B = iota, iota << 10 // 0, 0 << 10

C, D // 1, 1 << 10

)

如果 iota ?增被打斷,須顯式恢復(fù)屡贺。

const (

A = iota // 0

B // 1

C = "c" // c

D // c蠢棱,與上??相同。

E = iota // 4甩栈,顯式恢復(fù)泻仙。注意計(jì)數(shù)包含了 C、 D 兩?量没。

F // 5

)


package main

import "fmt"

func main() {

const (

? ? ?a = iota //0

? ? ?b //1

? ? ?c //2

? ? ?d = "ha" //獨(dú)?值玉转, iota += 1

? ? ?e //"ha" iota += 1?

? ? ?f = 100 //iota +=1

? ? ?g //100 iota +=1

? ? ?h = iota //7,恢復(fù)計(jì)數(shù)

? ? ?i //8

)

fmt.Println(a, b, c, d, e, f, g, h, i)

}

以上實(shí)例運(yùn)行結(jié)果為:

0 1 2 ha ha 100 100 7 8



1.3 基本類型

更明確的數(shù)字類型命名,?持 Unicode允蜈,?持常?數(shù)據(jù)結(jié)構(gòu)冤吨。序號(hào)類型和描述

1布爾型

布爾型的值只可以是常量 true 或者 false蒿柳。一個(gè)簡單的例子:var b bool = true。

2數(shù)字類型

整型 int 和浮點(diǎn)型 float32漩蟆、float64垒探,Go 語言支持整型和浮點(diǎn)型數(shù)字,并且原生支持復(fù)數(shù)怠李,其中位的運(yùn)算采用補(bǔ)碼圾叼。

3字符串類型:

字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個(gè)字節(jié)連接起來的捺癞。Go語言的字符串的字節(jié)使用UTF-8編碼標(biāo)識(shí)Unicode文本夷蚊。

4派生類型:

包括:

(a) 指針類型(Pointer)

(b) 數(shù)組類型

(c) 結(jié)構(gòu)化類型(struct)

(d) Channel 類型

(e) 函數(shù)類型?

(f) 切片類型?

(g) 接口類型(interface)

(h) Map 類型



1.4 引?類型

引?類型包括 slice、 map 和 channel髓介。它們有復(fù)雜的內(nèi)部結(jié)構(gòu)惕鼓,除了申請(qǐng)內(nèi)存外,還需

要初始化相關(guān)屬性唐础。

內(nèi)置函數(shù) new 計(jì)算類型??箱歧,為其分配零值內(nèi)存,返回指針。? make 會(huì)被編譯器翻譯

成具體的創(chuàng)建函數(shù),由其分配內(nèi)存和初始化成員結(jié)構(gòu)牡属,返回對(duì)象??指針。

a := []int{0, 0, 0} // 提供初始化表達(dá)式损痰。


a[1] = 10

b := make([]int, 3) // slice.c: runtime·makeslice

b[1] = 10

c := new([]int)

c[1] = 10 // Error: invalid operation: c[1] (index of type *[]int)

1.5 類型轉(zhuǎn)換

不?持隱式類型轉(zhuǎn)換,即便是從窄向?qū)掁D(zhuǎn)換也不?。

var b byte = 100

// var n int = b // Error: cannot use b (type byte) as type int in assignment

var n int = int(b) // 顯式轉(zhuǎn)換

使?括號(hào)避免優(yōu)先級(jí)錯(cuò)誤。

*Point(p) // 相當(dāng)于 *(Point(p))

(*Point)(p)

<-chan int(c) // 相當(dāng)于 <-(chan int(c))

(<-chan int)(c)

同樣不能將其他類型當(dāng) bool 值使?蝉衣。

a := 100

if ? a { ? ?// Error: non-bool a (type int) used as if condition

? println("true")

}



1.6 字符串

字符串是不可變值類型,內(nèi)部?指針指向 UTF-8 字節(jié)數(shù)組仲智。

? 默認(rèn)值是空字符串 ""买乃。

? ?索引號(hào)訪問某字節(jié),如 s[i]钓辆。

? 不能?序號(hào)獲取字節(jié)元素指針。 &s[i] ?法肴焊。

? 不可變類型前联,?法修改字節(jié)數(shù)組。

? 字節(jié)數(shù)組尾部不包含 NULL娶眷。

使?索引號(hào)訪問字符 (byte)似嗤。

s := "abc"

println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63)

輸出: ??true true true

使? "`" 定義不做轉(zhuǎn)義處理的原始字符串,?持跨?届宠。

s := `a

b\r\n\x00

c`

println(s)

輸出:

a

b\r\n\x00

c

連接跨?字符串時(shí)烁落, "+" 必須在上??末尾乘粒,否則導(dǎo)致編譯錯(cuò)誤。

s := "Hello, " + ? ?//必須加在上一行結(jié)尾

"World!"

s2 := "Hello, "

+ "World!" // Error: invalid operation: + untyped string

?持?兩個(gè)索引號(hào)返回?串伤塌。?串依然指向原字節(jié)數(shù)組灯萍,僅修改了指針和?度屬性。

s := "Hello, World!"

s1 := s[:5] // Hello ? //索引第一個(gè)元素到第五個(gè)

s2 := s[7:] // World! ? ?//索引第七個(gè)到最后一個(gè)

s3 := s[1:5] // ello

單引號(hào)字符常量表? Unicode Code Point每聪,?持 \uFFFF旦棉、 \U7FFFFFFF、 \xFF 格式药薯。

對(duì)應(yīng) 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

要修改字符串童本,可先將其轉(zhuǎn)換成 []rune 或 []byte真屯,完成后再轉(zhuǎn)換為 string。?論哪種轉(zhuǎn)

換穷娱,都會(huì)重新分配內(nèi)存讨跟,并復(fù)制字節(jié)數(shù)組。

func main() {

s := "abcd"

bs := []byte(s)

bs[1] = 'B'

println(string(bs)) ? //輸出: ?aBcd

u := "電腦"

us := []rune(u)

us[1] = '話'

println(string(us)) ? ? //電話

}


? for 循環(huán)遍歷字符串時(shí)鄙煤,也有 byte 和 rune 兩種?式晾匠。

func main() {

s := "abc漢字"

for i := 0; i < len(s); i++ { ? // byte

? ? fmt.Printf("%c,", s[i])

}

fmt.Println()

for _, r := range s { ? // rune

fmt.Printf("%c,", r)

}

}

輸出:

a,b,c,?,±,,?,-,,

a,b,c,漢,字,





1.7 指針

?持指針類型 *T,指針的指針 **T梯刚,以及包含包名前綴的 *<package>.T凉馆。

? 默認(rèn)值 nil,沒有 NULL 常量亡资。

? 操作符 "&" 取變量地址澜共, "*" 透過指針訪問?標(biāo)對(duì)象。

? 不?持指針運(yùn)算锥腻,不?持 "->" 運(yùn)算符嗦董,直接? "." 訪問成員


注意: GC 把 uintptr 當(dāng)成普通整數(shù)對(duì)象,它?法阻? "關(guān)聯(lián)" 對(duì)象被回收瘦黑。



1.8 ?定義類型

可將類型分為命名和未命名兩?類京革。命名類型包括 bool、 int幸斥、 string 等匹摇,? array、

slice甲葬、 map 等和具體元素類型廊勃、?度等有關(guān),屬于未命名類型经窖。

Go 學(xué)習(xí)筆記, 第 2 版

18

具有相同聲明的未命名類型被視為同?類型坡垫。

? 具有相同基類型的指針梭灿。

? 具有相同元素類型和?度的 array。

? 具有相同元素類型的 slice冰悠。

? 具有相同鍵值類型的 map堡妒。

? 具有相同元素類型和傳送?向的 channel。

? 具有相同字段序列 (字段名屿脐、類型涕蚤、標(biāo)簽、順序) 的匿名 struct的诵。

? 簽名相同 (參數(shù)和返回值万栅,不包括參數(shù)名稱) 的 function。

? ?法集相同 (?法名西疤、?法簽名相同烦粒,和次序?關(guān)) 的 interface。

var a struct { x int `a` }

var b struct { x int `ab` }

// cannot use a (type struct { x int "a" }) as type struct { x int "ab" } in assignment

b = a

可? type 在全局或函數(shù)內(nèi)定義新類型代赁。

func main() {

type bigint int64

var x bigint = 100

println(x)

}

新類型不是原類型的別名扰她,除擁有相同數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)外,它們之間沒有任何關(guān)系芭碍,不會(huì)持

有原類型任何信息徒役。除??標(biāo)類型是未命名類型,否則必須顯式轉(zhuǎn)換窖壕。

x := 1234

var b bigint = bigint(x) // 必須顯式轉(zhuǎn)換忧勿,除?是常量。

var b2 int64 = int64(b)

var s myslice = []int{1, 2, 3} // 未命名類型瞻讽,隱式轉(zhuǎn)換鸳吸。

var s2 []int = s



最后附上幾個(gè)學(xué)go語言必要的連接

golang標(biāo)準(zhǔn)庫文檔

go語言中文網(wǎng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市速勇,隨后出現(xiàn)的幾起案子晌砾,更是在濱河造成了極大的恐慌,老刑警劉巖烦磁,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件养匈,死亡現(xiàn)場離奇詭異,居然都是意外死亡个初,警方通過查閱死者的電腦和手機(jī)乖寒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來院溺,“玉大人,你說我怎么就攤上這事磅轻≌湟荩” “怎么了逐虚?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谆膳。 經(jīng)常有香客問我叭爱,道長,這世上最難降的妖魔是什么漱病? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任买雾,我火速辦了婚禮,結(jié)果婚禮上杨帽,老公的妹妹穿的比我還像新娘漓穿。我一直安慰自己,他們只是感情好注盈,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布晃危。 她就那樣靜靜地躺著,像睡著了一般老客。 火紅的嫁衣襯著肌膚如雪僚饭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天胧砰,我揣著相機(jī)與錄音鳍鸵,去河邊找鬼。 笑死尉间,一個(gè)胖子當(dāng)著我的面吹牛偿乖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乌妒,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼汹想,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撤蚊?” 一聲冷哼從身側(cè)響起古掏,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侦啸,沒想到半個(gè)月后槽唾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡光涂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年庞萍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忘闻。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钝计,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情私恬,我是刑警寧澤债沮,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站本鸣,受9級(jí)特大地震影響疫衩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荣德,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一闷煤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涮瞻,春花似錦鲤拿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至艇抠,卻和暖如春幕庐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背家淤。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工异剥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人絮重。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓冤寿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親青伤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子督怜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 3,845評(píng)論 0 6
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,836評(píng)論 0 38
  • Scala與Java的關(guān)系 Scala與Java的關(guān)系是非常緊密的!狠角! 因?yàn)镾cala是基于Java虛擬機(jī)号杠,也就是...
    燈火gg閱讀 3,452評(píng)論 1 24
  • 大約7億年前,地球經(jīng)歷了不同尋常的全球冷卻丰歌,地質(zhì)學(xué)家稱之為“雪球地球”姨蟋。 有人提出了一些理論來解釋是什么觸發(fā)了這一...
    wumingzhi111閱讀 765評(píng)論 0 1
  • 在項(xiàng)目中遇到了一個(gè)需求,就是把相冊(cè)的導(dǎo)航欄改掉,可以在彈出UIImagePicker的時(shí)候修改就像下面一樣 也可以...
    fighter0501閱讀 924評(píng)論 0 1