Go基礎(chǔ)語法(一)

image.png

先講一下,寫這種筆記的目的:

  1. 自己在學(xué)的過程中能一字一句讀下來并且寫出來,便于理解加深記憶,這樣做比只看教程記憶會更加深刻。
  2. 當(dāng)我某些細的點遺忘的時候我可以快速查詢,因為筆記是我自己寫的我知道知識點寫在哪部分。
  3. 可以分享出來給其他熱愛go的入門者或者在上學(xué)的同學(xué)看,因為這邊記錄的是把官方內(nèi)容精簡了些。

什么是Golang

Go 亦稱為 Golang(譯注:按照 Rob Pike 說法,語言叫做 Go,Golang 只是官方網(wǎng)站的網(wǎng)址),是由谷歌開發(fā)的一個開源的編譯型的靜態(tài)語言。

Golang 的主要關(guān)注點是使得高可用性和可擴展性的 Web 應(yīng)用的開發(fā)變得簡便容易。(譯注:Go 的定位是系統(tǒng)編程語言,只是對 Web 開發(fā)支持較好)

Go 語言一些優(yōu)點:

  • 并發(fā)是語言的一部分(并非通過標(biāo)準(zhǔn)庫實現(xiàn)),所以編寫多線程程序會是一件很容易的事。后續(xù)教程將會討論到,并發(fā)是通過 Goroutines 和 channels 機制實現(xiàn)的。
  • Golang 是一種編譯型語言。源代碼會編譯為二進制機器碼。而在解釋型語言中沒有這個過程,如 Nodejs 中的 Python。
  • 語言規(guī)范十分簡潔。所有規(guī)范都在一個頁面展示,你甚至都可以用它來編寫你自己的編譯器呢。
  • Go 編譯器支持靜態(tài)鏈接。所有 Go 代碼都可以靜態(tài)鏈接為一個大的二進制文件(譯注:相對現(xiàn)在的磁盤空間,其實根本不大),并可以輕松部署到云服務(wù)器,而不必擔(dān)心各種依賴性。

安裝

Mac OS

官網(wǎng)下載https://golang.org/dl/ 安裝程序。雙擊開始安裝,會將 Golang 安裝到 /usr/local/go 目錄下,同時 /usr/local/go/bin 文件夾也會被添加到 PATH 環(huán)境變量中。
(這里只介紹Mac OS下的安裝,其他平臺請自行查閱)

建立工作區(qū)

在 Mac 或 Linux 操作系統(tǒng)下,Go 工作區(qū)應(yīng)該設(shè)置在 $HOME/go。所以我們要在 $HOME 目錄下創(chuàng)建 go 目錄。
也可以通過設(shè)置 GOPATH ,用其他目錄來作為工作區(qū)。我這邊使用的ide是這個

image.png

設(shè)置GOPATH的方式:
image.png

所有 Go 源文件都應(yīng)該放置在工作區(qū)里的 src 目錄下。請在剛添加的 go 目錄下面創(chuàng)建目錄 src。

所有 Go 項目都應(yīng)該依次在 src 里面設(shè)置自己的子目錄。我們在 src 里面創(chuàng)建一個目錄 hello 來放置整個 hello 項目。

創(chuàng)建上述目錄之后,其目錄結(jié)構(gòu)如下:

go
   src
      hello
          hello.go

hello.go中寫入代碼:

package main

import "fmt"

func main() {  
    fmt.Println("Hello World")
}

  1. 使用命令go run hello.go名運行:


    image.png
  2. 使用 go install hello 命令
    當(dāng)你輸入 go install hello 時,go 工具會在工作區(qū)中搜索 hello 包。接下來它會在工作區(qū)的 bin 目錄下,創(chuàng)建一個名為 hello(Windows 下名為 hello.exe)的二進制文件。運行 go install hello 后,其目錄結(jié)構(gòu)如下所示:
go
  bin
    hello
  src
    hello
      hello.go

代碼中第一行:
package main ,每一個 Go 文件都應(yīng)該在開頭進行 package name 的聲明(譯注:只有可執(zhí)行程序的包名應(yīng)當(dāng)為 main)。包(Packages)用于代碼的封裝與重用,這里的包名稱是main。

變量

變量:變量指定了某存儲單元(Memory Location)的名稱,該存儲單元會存儲特定類型的值。在 Go 中,有多種語法用于聲明變量。

package main

import (
    "fmt"
    "math"
)

func main() {
    var age int // 變量聲明
    fmt.Println("my age is", age)

    age = 10   //變量賦值
    fmt.Println("my age is", age)

    age = 30  //變量賦值
    fmt.Println("my age is", age)

    var name string = "allen" // 聲明變量并初始化
    fmt.Println("my name is", name)

    var num = 29 // 可以推斷類型
    fmt.Println("my num is", num)

    var width, height int = 100, 50 // 聲明多個變量
    fmt.Println("width is", width, "height is", height)

    var a, b int //省略初始化,默認值為0
    fmt.Println("width is", a, "height is", b)

    //一個語句中聲名不同類型變量
    var (
        c  = "jie"
        d    = 24
        e int
    )
    fmt.Println("my c is", c, ", d is", d, "and e is", e)

    m, n := "allen", 29 // 簡短聲明
    fmt.Println("m name is", m, "n is", n)

    //變量也可以在運行時進行賦值
    q, p := 145.8, 543.8
    e1 := math.Min(q, p)
    fmt.Println("minimum value is ", e1)

}
  1. 聲明單個變量 :var name type
  2. 聲明變量并初始化 : var name type = initialvalue
  3. 類型推斷(Type Inference) : 如果變量有初始值,那么 Go 能夠自動推斷具有初始值的變量的類型。因此,如果變量有初始值,就可以在變量聲明中省略 type。例:var name = initialvalue
  4. 聲明多個變量 : var name1, name2 type = initialvalue1, initialvalue2。
  5. 一個語句中聲明不同類型的變量 :
    var (
    name1 = initialvalue1,
    name2 = initialvalue2
    )
  6. 簡短聲明 : name := initialvalue,
    簡短聲明要求 := 操作符左邊的所有變量都有初始值。
    簡短聲明的語法要求 := 操作符的左邊至少有一個變量是尚未聲明的。
  7. 由于 Go 是強類型(Strongly Typed)語言,因此不允許某一類型的變量賦值為其他類型的值。

類型

基本類型:

  • bool
  • 數(shù)字類型
    int8, int16, int32, int64, int
    uint8, uint16, uint32, uint64, uint
    float32, float64
    complex64, complex128
    byte
    rune
  • string
有符號整型:
image.png

int:根據(jù)不同的底層平臺(Underlying Platform),表示 32 或 64 位整型。除非對整型的大小有特定的需求,否則你通常應(yīng)該使用 int 表示整型。

在 Printf 方法中,使用%T打印變量類型。
Go 的 unsafe 包提供了一個 Sizeof 函數(shù),該函數(shù)接收變量并返回它的字節(jié)大小。

func main()  {
    a := true
    b := false
    fmt.Println("a:", a, "b:", b)
    c := a && b //僅當(dāng) a 和 b 都為 true 時,操作符 && 才返回 true
    fmt.Println("c:", c)
    d := a || b //當(dāng) a 或者 b 為 true 時,操作符 || 返回 true
    fmt.Println("d:", d)


    var a1 int = 89
    b1 := 95
    fmt.Println("a1 is", a1, "and b is", b1)
    fmt.Printf("type of a is %T, size of a is %d", a1, unsafe.Sizeof(a1)) // a 的類型和大小
    fmt.Printf("\ntype of b is %T, size of b is %d", b1, unsafe.Sizeof(b1)) // b 的類型和大小
}

在32位系統(tǒng)下,字節(jié)大小為4,64位下,字節(jié)大小為8。

無符號整型
image.png

uint:根據(jù)不同的底層平臺,表示 32 或 64 位無符號整型。

浮點型

float32:32 位浮點數(shù)
float64:64 位浮點數(shù)

package main

import (  
    "fmt"
)

func main() {
    a, b := 5.67, 8.97 //a 和 b 的類型根據(jù)賦值推斷得出,float64 是浮點數(shù)的默認類型
    fmt.Printf("type of a %T b %T\n", a, b)
    sum := a + b
    diff := a - b
    fmt.Println("sum", sum, "diff", diff)

    no1, no2 := 56, 89
    fmt.Println("sum", no1+no2, "diff", no1-no2)
}

a 和 b 的類型根據(jù)賦值推斷得出,float64 是浮點數(shù)的默認類型。

復(fù)數(shù)類型

complex64:實部和虛部都是 float32 類型的的復(fù)數(shù)。
complex128:實部和虛部都是 float64 類型的的復(fù)數(shù)。

其他數(shù)字類型

byte 是 uint8 的別名。
rune 是 int32 的別名。

string 類型

在 Golang 中,字符串是字節(jié)的集合。如果你現(xiàn)在還不理解這個定義,也沒有關(guān)系。我們可以暫且認為一個字符串就是由很多字符組成的。后面會在一個教程中深入學(xué)習(xí)字符串。

package main

import (  
    "fmt"
)

func main() {  
    first := "Zhao"
    last := "Alle"
    name := first +" "+ last
    fmt.Println("My name is",name)
}

類型轉(zhuǎn)換

Go 有著非常嚴格的強類型特征。Go 沒有自動類型提升或類型轉(zhuǎn)換。

package main

import (  
    "fmt"
)

func main() {
    i := 55      //int
    j := 67.8    //float64
    sum := i + int(j) //j is converted to int
    fmt.Println(sum)

    q := 10
    var w float64 = float64(q) // 若沒有顯式轉(zhuǎn)換,該語句會報錯
    fmt.Println("w", w)
}

把 v 轉(zhuǎn)換為 T 類型的語法是 T(v)。
賦值的情況也是如此。把一個變量賦值給另一個不同類型的變量,需要顯式的類型轉(zhuǎn)換。

常量

定義:在 Go 語言中,術(shù)語"常量"用于表示固定的值。
使用關(guān)鍵字 const 表示常量。

package main

func main() {  
    const a = 55 // 允許
    a = 89       // 不允許重新賦值
}
  1. 常量不能再重新賦值為其他的值。因此上面的代碼將不能正常工作,它將出現(xiàn)一個編譯錯誤: cannot assign to a
  2. 常量的值會在編譯的時候確定。因為函數(shù)調(diào)用發(fā)生在運行時,所以不能將函數(shù)的返回值賦值給常量。

字符串常量

const a = "Hello World"
上面的例子,我們把 Hello World 分配給常量 a?,F(xiàn)在常量 a 是沒有類型的。

無類型的常量有一個與它們相關(guān)聯(lián)的默認類型(上邊默認類型是string),并且當(dāng)且僅當(dāng)一行代碼需要時才提供它。在聲明中 var b = "Sam" , b 需要一個類型,它從字符串常量 Sam 的默認類型中獲取。

創(chuàng)建一個帶類型的常量:
const c string = "Hello World"
常量c就是一個string類型的。

Go 是一個強類型的語言,在分配過程中混合類型是不允許的。

布爾常量

布爾常量和字符串常量用法相同,他們是兩個無類型的常量 true 和 false。

package main

func main() {  
    const trueConst = true
    type myBool bool
    var defaultBool = trueConst // 允許
    var customBool myBool = trueConst // 允許
    defaultBool = customBool // 不允許
}

數(shù)字常量

包含整數(shù)、浮點數(shù)和復(fù)數(shù)的常量

func main() {
    const a = 5
    var intVar int = a
    var int32Var int32 = a
    var float64Var float64 = a
    var complex64Var complex64 = a
    fmt.Println("intVar",intVar, "\nint32Var", int32Var, "\nfloat64Var", float64Var, "\ncomplex64Var",complex64Var)
}

常量a 的值是 5 ,a 的語法是通用的(它可以代表一個浮點數(shù)、整數(shù)甚至是一個沒有虛部的復(fù)數(shù)),因此可以將其分配給任何兼容的類型。這些常量的默認類型可以被認為是根據(jù)上下文在運行中生成的。 var intVar int = a 要求 a 是 int,所以它變成一個 int 常量。 var complex64Var complex64 = a 要求 a 是 complex64,因此它變成一個復(fù)數(shù)類型。

數(shù)字表達式

func main() {  
    var a = 5.9/8
    fmt.Printf("a's type %T value %v",a, a)
}

在上面的程序中, 5.9 在語法中是浮點型,8 是整型,5.9/8 是允許的,因為兩個都是數(shù)字常量。除法的結(jié)果是 0.7375 是一個浮點型,所以 a 的類型是浮點型。

如果內(nèi)容對你有幫助,記得關(guān)注作者給個贊哦~,后續(xù)會持續(xù)更新。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容