go學(xué)習(xí)筆記(一)

變量

var num int;var num int = 1,var a,b int;var a,b int = 1,2;var a = 1;_,b=1,2;

1纠拔,:=這個符號直接取代了var和type,這種形式叫做簡短聲明。不過它有一個限制泛豪,那就是它只能用在函數(shù)內(nèi)部稠诲;在函數(shù)外部使用則會無法編譯通過,所以一般用var方式來定義全局變量诡曙。

2臀叙,_(下劃線)是個特殊的變量名,任何賦予它的值都會被丟棄价卤。

3劝萤,Go對于已聲明但未使用的變量會在編譯階段報錯

常量

const Pi=3.1415926;const i =10000;const MaxThread=10;const prefix ="astaxie_"

所謂常量,也就是在程序編譯階段就確定下來的值荠雕,而程序在運(yùn)行時無法改變該值稳其。在Go程序中,常量可定義為數(shù)值炸卑、布爾值或字符串等類型

數(shù)值

整數(shù)類型有無符號和帶符號兩種既鞠。Go同時支持int和uint,這兩種類型的長度相同盖文,但具體長度取決于不同編譯器的實(shí)現(xiàn)嘱蛋。Go里面也有直接定義好位數(shù)的類型:rune,?int8,?int16,?int32,?int64和byte,?uint8,?uint16,?uint32,?uint64。其中rune是int32的別稱,byte是uint8的別稱洒敏。

注:這些類型的變量之間不允許互相賦值或操作龄恋,不然會在編譯時引起編譯器報錯。另外凶伙,盡管int的長度是32 bit, 但int 與 int32并不可以互用郭毕。浮點(diǎn)數(shù)的類型有float32和float64兩種(沒有float類型),默認(rèn)是float64函荣。

字符串

Go中的字符串都是采用UTF-8字符集編碼显押。字符串是用一對雙引號("")或反引號(`?`)括起來定義,它的類型是string傻挂。

注:在Go中字符串是不可變的乘碑,若一定要修改,可以將字符串 s 轉(zhuǎn)換為 []byte 類型金拒,再轉(zhuǎn)換回 string 類型兽肤,Go中可以使用+操作符來連接兩個字符串,字符串雖不能更改绪抛,但可進(jìn)行切片操作资铡,如果要聲明一個多行的字符串怎么辦?可以通過`來聲明睦疫。

array害驹、slice、map

array就是數(shù)組蛤育,var arr [n]type宛官,長度也是數(shù)組類型的一部分,因此[3]int與[4]int是不同的類型瓦糕,數(shù)組也就不能改變長度底洗。數(shù)組之間的賦值是值的賦值,即當(dāng)把一個數(shù)組作為參數(shù)傳入函數(shù)的時候咕娄,傳入的其實(shí)是該數(shù)組的副本亥揖,而不是它的指針。如果要使用指針圣勒,那么就需要用到后面介紹的slice類型了费变。

“動態(tài)數(shù)組”,在Go里面這種數(shù)據(jù)結(jié)構(gòu)叫slice圣贸,slice并不是真正意義上的動態(tài)數(shù)組挚歧,而是一個引用類型。slice總是指向一個底層array吁峻,slice的聲明也可以像array一樣滑负,只是不需要長度在张。slice可以從一個數(shù)組或一個已經(jīng)存在的slice中再次聲明。slice通過array[i:j]來獲取矮慕,其中i是數(shù)組的開始位置帮匾,j是結(jié)束位置,但不包含array[j]痴鳄,它的長度是j-i瘟斜,類似于python的切片或者c++的vector。

從概念上面來說slice像一個結(jié)構(gòu)體夏跷,這個結(jié)構(gòu)體包含了三個元素:

一個指針哼转,指向數(shù)組中slice指定的開始位置。

長度槽华,即slice的長度。

最大長度趟妥,也就是slice開始位置到數(shù)組的最后位置的長度猫态。

對于slice有幾個有用的內(nèi)置函數(shù):

len?獲取slice的長度

cap?獲取slice的最大容量

append?向slice里面追加一個或者多個元素,然后返回一個和slice一樣類型的slice

copy?函數(shù)copy從源slice的src中復(fù)制元素到目標(biāo)dst披摄,并且返回復(fù)制的元素的個數(shù)

注:append函數(shù)會改變slice所引用的數(shù)組的內(nèi)容亲雪,從而影響到引用同一數(shù)組的其它slice。 但當(dāng)slice中沒有剩余空間(即(cap-len) == 0)時疚膊,此時將動態(tài)分配新的數(shù)組空間义辕。返回的slice數(shù)組指針將指向這個空間,而原數(shù)組的內(nèi)容將保持不變寓盗;其它引用此數(shù)組的slice則不受影響灌砖。

注意:slice和數(shù)組在聲明時的區(qū)別:聲明數(shù)組時,方括號內(nèi)寫明了數(shù)組的長度或使用...自動計算長度傀蚌,而聲明slice時基显,方括號內(nèi)沒有任何字符。slice是引用類型善炫,所以當(dāng)引用改變其中元素的值時撩幽,其它的所有引用都會改變該值。

map類似python中的字典箩艺。聲明舉例:var numbersmap [string]int窜醉,numbers =make(map[string]int)。

使用map過程中需要注意的幾點(diǎn):

map是無序的艺谆,每次打印出來的map都會不一樣榨惰,它不能通過index獲取,而必須通過key獲取

map的長度是不固定的擂涛,也就是和slice一樣读串,也是一種引用類型

內(nèi)置的len函數(shù)同樣適用于map聊记,返回map擁有的key的數(shù)量

map的值可以很方便的修改,通過numbers["one"]=11可以很容易的把key為one的字典值改為11

map和其他基本型別不同恢暖,它不是thread-safe排监,在多個go-routine存取時,必須使用mutex lock機(jī)制

map的初始化可以通過key:val的方式初始化值杰捂,同時map內(nèi)置有判斷是否存在key的方式

通過delete刪除map的元素:

map也是一種引用類型舆床,如果兩個map同時指向一個底層,那么一個改變嫁佳,另一個也相應(yīng)的改變

make挨队、new操作

make用于內(nèi)建類型(map、slice?和channel)的內(nèi)存分配蒿往。new用于各種類型的內(nèi)存分配盛垦。

注:new返回指針。make返回初始化后的(非零)值瓤漏。make 只能為 slice腾夯、map或 channel 類型分配內(nèi)存并初始化,同時返回一個有初始值的 slice蔬充、map 或 channel 類型引用蝶俱,不是指針。內(nèi)建函數(shù) new 用來分配內(nèi)存饥漫,它的第一個參數(shù)是一個類型榨呆,不是一個值,它的返回值是一個指向新分配類型零值的指針庸队。

流程控制

Go里面if條件判斷語句中不需要括號积蜻,Go的if還有一個強(qiáng)大的地方就是條件判斷語句里面允許聲明一個變量,這個變量的作用域只能在該條件邏輯塊內(nèi)皿哨,其他地方就不起作用了浅侨,比如if x=1;x>0{執(zhí)行體}。

goto類似c語言中的goto证膨,

for如输,在循環(huán)里面有兩個關(guān)鍵操作break和continue ,break操作是跳出當(dāng)前循環(huán),continue是跳過本次循環(huán)央勒。當(dāng)嵌套過深的時候不见,break可以配合標(biāo)簽使用,即跳轉(zhuǎn)至標(biāo)簽所指定的位置崔步,break和continue還可以跟著標(biāo)號稳吮,用來跳到多重循環(huán)中的外層循環(huán)。

switch井濒,類似與c的switch灶似,Go里面switch默認(rèn)相當(dāng)于每個case最后帶有break列林,匹配成功后不會自動向下執(zhí)行其他case,而是跳出整個switch酪惭,但是可以使用fallthrough強(qiáng)制執(zhí)行后面的case代碼希痴。

函數(shù)

注:函數(shù)可以返回多個值。Go函數(shù)支持變參春感,如 func myfunc(arg...int) {}砌创。

傳值,當(dāng)我們傳一個參數(shù)值到被調(diào)用函數(shù)里面時鲫懒,實(shí)際上是傳了這個值的一份copy嫩实,當(dāng)在被調(diào)用函數(shù)中修改參數(shù)值的時候,調(diào)用函數(shù)中相應(yīng)實(shí)參不會發(fā)生任何變化窥岩,因?yàn)閿?shù)值變化只作用在copy上甲献。

傳指針使得多個函數(shù)能操作同一個對象。傳指針比較輕量級 (8bytes),只是傳內(nèi)存地址颂翼,我們可以用指針傳遞體積大的結(jié)構(gòu)體竟纳。如果用參數(shù)值傳遞的話, 在每次copy上面就會花費(fèi)相對較多的系統(tǒng)開銷(內(nèi)存和時間)。所以當(dāng)你要傳遞大的結(jié)構(gòu)體的時候疚鲤,用指針是一個明智的選擇。Go語言中channel缘挑,slice集歇,map這三種類型的實(shí)現(xiàn)機(jī)制類似指針,所以可以直接傳遞语淘,而不用取地址后傳遞指針诲宇。(注:若函數(shù)需改變slice的長度,則仍需要取地址傳遞指針)

defer惶翻,Go語言中有種不錯的設(shè)計姑蓝,即延遲(defer)語句,你可以在函數(shù)中添加多個defer語句吕粗。當(dāng)函數(shù)執(zhí)行到最后時纺荧,這些defer語句會按照逆序執(zhí)行,最后該函數(shù)返回颅筋。

函數(shù)作為值宙暇、類型。在Go中函數(shù)也是一種變量议泵,我們可以通過type來定義它占贫,它的類型就是所有擁有相同的參數(shù),相同的返回值的一種類型先口。函數(shù)當(dāng)做值和類型在我們寫一些通用接口的時候非常有用型奥。

Panic和Recover

Panic是一個內(nèi)建函數(shù)瞳收,可以中斷原有的控制流程,進(jìn)入一個panic狀態(tài)中厢汹。當(dāng)函數(shù)F調(diào)用panic螟深,函數(shù)F的執(zhí)行被中斷,但是F中的延遲函數(shù)defer會正常執(zhí)行坑匠,然后F返回到調(diào)用它的地方血崭。在調(diào)用的地方,F(xiàn)的行為就像調(diào)用了panic厘灼。這一過程繼續(xù)向上夹纫,直到發(fā)生panic的goroutine中所有調(diào)用的函數(shù)返回,此時程序退出设凹。panic可以直接調(diào)用panic產(chǎn)生舰讹。也可以由運(yùn)行時錯誤產(chǎn)生,例如訪問越界的數(shù)組闪朱。

Recover是一個內(nèi)建的函數(shù)月匣,可以讓進(jìn)入panic狀態(tài)的goroutine恢復(fù)過來。recover僅在延遲函數(shù)defer中有效奋姿。在正常的執(zhí)行過程中锄开,調(diào)用recover會返回nil,并且沒有其它任何效果称诗。如果當(dāng)前的goroutine陷入panic狀態(tài)萍悴,調(diào)用recover可以捕獲到panic的輸入值,并且恢復(fù)正常的執(zhí)行寓免。

main函數(shù)和init函數(shù)

Go里面有兩個保留的函數(shù):init函數(shù)(能夠應(yīng)用于所有的package)和main函數(shù)(只能應(yīng)用于package main)癣诱。這兩個函數(shù)在定義時不能有任何的參數(shù)和返回值。雖然一個package里面可以寫任意多個init函數(shù)袜香,但這無論是對于可讀性還是以后的可維護(hù)性來說撕予,我們都強(qiáng)烈建議用戶在一個package中每個文件只寫一個init函數(shù)。

Go程序會自動調(diào)用init()和main()蜈首,所以你不需要在任何地方調(diào)用這兩個函數(shù)实抡。每個package中的init函數(shù)都是可選的,但package main就必須包含一個main函數(shù)疾就。

程序的初始化和執(zhí)行都起始于main包澜术。如果main包還導(dǎo)入了其它的包,那么就會在編譯時將它們依次導(dǎo)入猬腰。有時一個包會被多個包同時導(dǎo)入鸟废,那么它只會被導(dǎo)入一次(例如很多包可能都會用到fmt包,但它只會被導(dǎo)入一次姑荷,因?yàn)闆]有必要導(dǎo)入多次)盒延。當(dāng)一個包被導(dǎo)入時缩擂,如果該包還導(dǎo)入了其它的包,那么會先將其它包導(dǎo)入進(jìn)來添寺,然后再對這些包中的包級常量和變量進(jìn)行初始化胯盯,接著執(zhí)行init函數(shù)(如果有的話),依次類推计露。等所有被導(dǎo)入的包都加載完畢了博脑,就會開始對main包中的包級常量和變量進(jìn)行初始化,然后執(zhí)行main包中的init函數(shù)(如果存在的話)票罐,最后執(zhí)行main函數(shù)叉趣。下圖詳細(xì)地解釋了整個執(zhí)行過程:

import這個命令用來導(dǎo)入包文件,類似于include该押,

import . "fmt" 點(diǎn)操作的含義就是這個包導(dǎo)入之后在你調(diào)用這個包的函數(shù)時疗杉,你可以省略前綴的包名

import f “fmt” 別名 fmt.Printf()->f.Printf()

import _ “fmt” _操作其實(shí)是引入該包,而不直接使用包里面的函數(shù)蚕礼,而是調(diào)用了該包里面的init函數(shù)烟具。

struct類型

和C語言類似

定義:

type person struct {

??????? name strin

??????? gage int

}

1.按照順序提供初始化值

P := person{"Tom", 25}

2.通過field:value的方式初始化,這樣可以任意順序

P := person{age:24, name:"Tom"}

3.當(dāng)然也可以通過new函數(shù)分配一個指針奠蹬,此處P的類型為*person

P := new(person)

匿名字段:Go支持只提供類型朝聋,而不寫字段名的方式,也就是匿名字段囤躁,也稱為嵌入字段玖翅。當(dāng)匿名字段是一個struct的時候,那么這個struct所擁有的全部字段都被隱式地引入了當(dāng)前定義的這個struct割以。通過匿名訪問和修改字段相當(dāng)?shù)挠杏茫遣粌H僅是struct字段哦应媚,所有的內(nèi)置類型(int string等)和自定義類型都是可以作為匿名字段的严沥。

注:結(jié)構(gòu)中匿名字段和結(jié)構(gòu)本身字段重名,Go里面很簡單的解決了這個問題中姜,最外層的優(yōu)先訪問

面向?qū)ο?/b>

通俗的說就是給struct綁定了函數(shù)消玄,函數(shù)接收者可以時值copy,也可以是指針丢胚,

method的語法如下:

func (r ReceiverType) funcName(parameters) (results)

在使用method的時候重要注意幾點(diǎn)

雖然method的名字一模一樣翩瓜,但是如果接收者不一樣,那么method就不一樣

method里面可以訪問接收者的字段

調(diào)用method通過.訪問携龟,就像struct里面訪問字段一樣

method 重寫兔跌,繼承。

舉例

package main

import "fmt"

type Human struct {

? ? name? string

? ? age? int

? ? phone string // Human類型擁有的字段

}

type Student struct {

? ? Human

? ? school string

? ? phone? string

}

type Employee struct {

? ? Human? ? ? // 匿名字段Human

? ? speciality string

? ? phone? ? ? string // 雇員的phone字段

}

func (h Human) say() {

? ? fmt.Println(h.name, h.age, h.phone)

}+++

func (h Employee) say() {

? ? fmt.Println(h.name, h.age, h.phone, h.speciality, h.Human.phone)

}

func main() {

? ? Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}

? ? Tom := Student{Human{"Tom", 18, "123-456-189"}, "yichuan", "666"}

? ? Tom.say()

? ? Bob.say()

? ? fmt.Println(Tom.phone, Tom.Human.phone)


注:以上筆記基本來自

https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/preface.md

作為業(yè)余愛好僅僅記錄了一些注意點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末峡蟋,一起剝皮案震驚了整個濱河市坟桅,隨后出現(xiàn)的幾起案子华望,更是在濱河造成了極大的恐慌,老刑警劉巖仅乓,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赖舟,死亡現(xiàn)場離奇詭異,居然都是意外死亡夸楣,警方通過查閱死者的電腦和手機(jī)宾抓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豫喧,“玉大人石洗,你說我怎么就攤上這事『偌” “怎么了劲腿?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸟妙。 經(jīng)常有香客問我焦人,道長,這世上最難降的妖魔是什么重父? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任花椭,我火速辦了婚禮,結(jié)果婚禮上房午,老公的妹妹穿的比我還像新娘矿辽。我一直安慰自己,他們只是感情好郭厌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布袋倔。 她就那樣靜靜地躺著,像睡著了一般折柠。 火紅的嫁衣襯著肌膚如雪宾娜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天扇售,我揣著相機(jī)與錄音前塔,去河邊找鬼。 笑死承冰,一個胖子當(dāng)著我的面吹牛华弓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播困乒,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼寂屏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凑保,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤冈爹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后欧引,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體频伤,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年芝此,在試婚紗的時候發(fā)現(xiàn)自己被綠了憋肖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡婚苹,死狀恐怖岸更,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膊升,我是刑警寧澤怎炊,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站廓译,受9級特大地震影響评肆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫁审。 院中可真熱鬧,春花似錦久橙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至渤弛,卻和暖如春吭敢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暮芭。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欲低,地道東北人辕宏。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像砾莱,于是被迫代替她去往敵國和親瑞筐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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