Go 語言官方教程-學(xué)習(xí)指南-快速入門

新人作者求點(diǎn)贊 ^^
bilibili事件發(fā)生后,忽然意識到這么高大上的bilibili竟然是用Go(golang)語言寫的橙喘。忍不住我也要開始學(xué)這門有趣的語言时鸵。

其實(shí)Go官方是有非常好的中文版官方教程的,尊重版權(quán)[1] Golang Doc 厅瞎。

這里我與大家分享出來一些文檔的重點(diǎn)饰潜,首先是基礎(chǔ)篇的內(nèi)容,學(xué)完就能正式入門Go了和簸,希望大家能happy彭雾。(我邊學(xué)邊更新~)


每個(gè) Go 程序都是由包構(gòu)成的。

程序從 main 包開始運(yùn)行锁保。

本程序通過導(dǎo)入路徑 "fmt""math/rand" 來使用這兩個(gè)包薯酝。

按照約定半沽,包名與導(dǎo)入路徑的最后一個(gè)元素一致。例如吴菠,"math/rand" 包中的源碼均以 package rand 語句開始者填。

注意: 此程序的運(yùn)行環(huán)境是固定的,因此 rand.Intn 總是會(huì)返回相同的數(shù)字做葵。 (要得到不同的數(shù)字占哟,需為生成器提供不同的種子數(shù),參見 rand.Seed酿矢。 練習(xí)場中的時(shí)間為常量榨乎,因此你需要用其它的值作為種子數(shù)。)

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Println("My favorite number is", rand.Intn(10))
}

導(dǎo)入

此代碼用圓括號組合了導(dǎo)入瘫筐,這是“分組”形式的導(dǎo)入語句蜜暑。

當(dāng)然你也可以編寫多個(gè)導(dǎo)入語句,例如:

import "fmt"
import "math"

不過使用分組導(dǎo)入語句是更好的形式严肪。

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Printf("Now you have %g problems.\n", math.Sqrt(7))
}

導(dǎo)出名

在 Go 中史煎,如果一個(gè)名字以大寫字母開頭,那么它就是已導(dǎo)出的驳糯。例如,Pizza 就是個(gè)已導(dǎo)出名氢橙,Pi 也同樣酝枢,它導(dǎo)出自 math 包。

pizzapi 并未以大寫字母開頭悍手,所以它們是未導(dǎo)出的帘睦。

在導(dǎo)入一個(gè)包時(shí),你只能引用其中已導(dǎo)出的名字坦康。任何“未導(dǎo)出”的名字在該包外均無法訪問竣付。

執(zhí)行代碼,觀察錯(cuò)誤輸出滞欠。

然后將 math.pi 改名為 math.Pi 再試著執(zhí)行一次古胆。

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.Pi)
}

函數(shù)

函數(shù)可以沒有參數(shù)或接受多個(gè)參數(shù)。

在本例中筛璧,add 接受兩個(gè) int 類型的參數(shù)。

注意類型在變量名 之后夭谤。

(參考 這篇關(guān)于 Go 語法聲明的文章了解這種類型聲明形式出現(xiàn)的原因棺牧。)

package main

import "fmt"

func add(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(add(1, 2))
}

函數(shù)(續(xù))

當(dāng)連續(xù)兩個(gè)或多個(gè)函數(shù)的已命名形參類型相同時(shí)朗儒,除最后一個(gè)類型以外参淹,其它都可以省略。

在本例中乏悄,

x int, y int

被縮寫為

x, y int

package main

import "fmt"

func add(x, y double) int {
    return x + y
}

func main() {
    fmt.Println(add(42, 13))
}

多值返回

函數(shù)可以返回任意數(shù)量的返回值浙值。

swap 函數(shù)返回了兩個(gè)字符串。

package main

import "fmt"

func swap(x, y string) (string, string) {
    return y, x
}

func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}

命名返回值

Go 的返回值可被命名纲爸,它們會(huì)被視作定義在函數(shù)頂部的變量亥鸠。

返回值的名稱應(yīng)當(dāng)具有一定的意義,它可以作為文檔使用识啦。

沒有參數(shù)的 return 語句返回已命名的返回值负蚊。也就是 直接 返回。

直接返回語句應(yīng)當(dāng)僅用在下面這樣的短函數(shù)中颓哮。在長的函數(shù)中它們會(huì)影響代碼的可讀性家妆。

package main

import "fmt"

func split(sum int) (x int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

func main() {
    fmt.Println(split(17))
}

變量

var 語句用于聲明一個(gè)變量列表,跟函數(shù)的參數(shù)列表一樣冕茅,類型在最后伤极。

就像在這個(gè)例子中看到的一樣,var 語句可以出現(xiàn)在包或函數(shù)級別姨伤。

package main

import "fmt"

var c, python, java bool

func main() {
    var i int
    fmt.Println(i, c, python, java)
}

變量的初始化

變量聲明可以包含初始值哨坪,每個(gè)變量對應(yīng)一個(gè)。

如果初始化值已存在乍楚,則可以省略類型当编;變量會(huì)從初始值中獲得類型。

package main

import "fmt"

var i, j int = 1, 2

func main() {
    var c, python, java = true, false, "no!"
    fmt.Println(i, j, c, python, java)
}

短變量聲明

在函數(shù)中徒溪,簡潔賦值語句 := 可在類型明確的地方代替 var 聲明忿偷。

函數(shù)外的每個(gè)語句都必須以關(guān)鍵字開始(var, func 等等),因此 := 結(jié)構(gòu)不能在函數(shù)外使用臊泌。

package main

import "fmt"

func main() {
    var i, j int = 1, 2
    var p bool
    k := 1.1

    c, python, java := true, false, "no!"

    fmt.Println(i, j, p,k, c, python, java)
}

基本類型

Go 的基本類型有

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 的別名

rune // int32 的別名
    // 表示一個(gè) Unicode 碼點(diǎn)

float32 float64

complex64 complex128

本例展示了幾種類型的變量鲤桥。 同導(dǎo)入語句一樣,變量聲明也可以“分組”成一個(gè)語法塊渠概。

int, uintuintptr 在 32 位系統(tǒng)上通常為 32 位寬茶凳,在 64 位系統(tǒng)上則為 64 位寬。 當(dāng)你需要一個(gè)整數(shù)值時(shí)應(yīng)使用 int類型高氮,除非你有特殊的理由使用固定大小或無符號的整數(shù)類型慧妄。

package main

import (
    "fmt"
    "math/cmplx"
)

var (
    ToBe   bool       = false
    MaxInt uint64     = 1<<64 - 1
    z      complex128 = cmplx.Sqrt(-5 + 12i)
)

func main() {
    fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe)
    fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt)
    fmt.Printf("Type: %T Value: %v\n", z, z)
}

零值

沒有明確初始值的變量聲明會(huì)被賦予它們的 零值

零值是:

  • 數(shù)值類型為 0剪芍,
  • 布爾類型為 false冯吓,
  • 字符串為 ""(空字符串)惩嘉。
package main

import "fmt"

func main() {
    var i int
    var f float64
    var b bool
    var s string
    fmt.Printf("%v %v %v %q\n", i, f, b, s)
}

類型轉(zhuǎn)換

表達(dá)式 T(v) 將值 v 轉(zhuǎn)換為類型 T纹笼。

一些關(guān)于數(shù)值的轉(zhuǎn)換:

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)

或者,更加簡單的形式:

i := 42
f := float64(i)
u := uint(f)

與 C 不同的是运挫,Go 在不同類型的項(xiàng)之間賦值時(shí)需要顯式轉(zhuǎn)換。試著移除例子中 float64uint 的轉(zhuǎn)換看看會(huì)發(fā)生什么套耕。

package main

import (
    "fmt"
    "math"
)

func main() {
    var x, y int = 3, 4
    var f float64 = math.Sqrt(float64(x*x + y*y))
    var z int = int(f)
    fmt.Println(x, y, z)
}

類型推導(dǎo)

在聲明一個(gè)變量而不指定其類型時(shí)(即使用不帶類型的 := 語法或 var = 表達(dá)式語法)谁帕,變量的類型由右值推導(dǎo)得出冯袍。

當(dāng)右值聲明了類型時(shí),新變量的類型與其相同:

var i int
j := i // j 也是一個(gè) int

不過當(dāng)右邊包含未指明類型的數(shù)值常量時(shí)康愤,新變量的類型就可能是 int, float64complex128 了,這取決于常量的精度:

i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

嘗試修改示例代碼中 v 的初始值征冷,并觀察它是如何影響類型的。

package main

import "fmt"

func main() {
    v := 42.00000000000001 // 修改這里检激!
    fmt.Printf("v is of type %T\n", v)
}

常量

常量的聲明與變量類似,只不過是使用 const 關(guān)鍵字叔收。

常量可以是字符、字符串缤灵、布爾值或數(shù)值。

常量不能用 := 語法聲明。

package main

import "fmt"

const Pi = 3.14

func main() {
    const World = "世界"
    fmt.Println("Hello", World)
    fmt.Println("Happy", Pi, "Day")

    const Truth = true
    fmt.Println("Go rules?", Truth)
}

數(shù)值常量

數(shù)值常量是高精度的 帖鸦。

一個(gè)未指定類型的常量由上下文來決定其類型。

再嘗試一下輸出 needInt(Big) 吧作儿。

int 類型最大可以存儲(chǔ)一個(gè) 64 位的整數(shù),有時(shí)會(huì)更小攻锰。)

int 可以存放最大64位的整數(shù),根據(jù)平臺(tái)不同有時(shí)會(huì)更少娶吞。)

package main

import "fmt"

const (
    // 將 1 左移 100 位來創(chuàng)建一個(gè)非常大的數(shù)字
    // 即這個(gè)數(shù)的二進(jìn)制是 1 后面跟著 100 個(gè) 0
    Big = 1 << 100
    // 再往右移 99 位,即 Small = 1 << 1机断,或者說 Small = 2
    Small = Big >> 99
)

func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
    return x * 0.1
}

func main() {
    fmt.Println(needInt(Small))
    fmt.Println(needFloat(Small))
    fmt.Println(needFloat(Big))
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吏奸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奋蔚,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坤按,死亡現(xiàn)場離奇詭異,居然都是意外死亡晋涣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門谢鹊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來留凭,“玉大人,你說我怎么就攤上這事蔼夜。” “怎么了求冷?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拯坟。 經(jīng)常有香客問我,道長郁季,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任梦裂,我火速辦了婚禮盖淡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘禁舷。我一直安慰自己毅往,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布攀唯。 她就那樣靜靜地躺著渴丸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谱轨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天诗茎,我揣著相機(jī)與錄音,去河邊找鬼敢订。 笑死,一個(gè)胖子當(dāng)著我的面吹牛罢吃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尿招,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怪蔑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饮睬,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤篮奄,失蹤者是張志新(化名)和其女友劉穎割去,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呻逆,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年茬腿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片切平。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖悴品,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苔严,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布届氢,位于F島的核電站,受9級特大地震影響退子,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜絮供,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缚俏。 院中可真熱鬧,春花似錦贮乳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刹缝。三九已至,卻和暖如春颈将,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晴圾。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留人乓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓色罚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親保屯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345