go 學習記錄--基礎語法

Al1en發表於2020-03-17

本期將go中的基礎語法模組通過程式碼的方式寫了一遍。
上傳到了github.後續將不斷通過更新專案總結go的學習以及總結。
下面的語法講解轉自golang官網,我簡寫了程式碼事例程式碼
golang官網:https://golang.google.cn/ref/spec
golang開源社群:http://tour.studygolang.com/welcome/1

程式碼地址:https://github.com/A1len/study-go


導讀

  • 基礎語法
  • 流程控制語句

基礎語法

這一部分將對go中的包、函式、申明變數、基本資料型別、常量做一個描述


Go程式是通過將程式包關聯在一起而組成。一個包又由一個或多個go原始檔組成,這些原始檔一起宣告瞭屬於該包的常量,型別,變數和函式,並且可以在同一包的所有檔案中進行訪問。這些元素可以 匯出並在另一個包中使用。

import (
  "fmt"
  "math"
)
//1.通過import的方式匯入包,可以像java一樣多個imprt匯入
//也可以通過上述方式  
​
​
​
//2.在匯入了一個包之後,就可以用其匯出的名稱來呼叫它。
//在 Go 中,首字母大寫的名稱是被匯出的。
//Foo 和 FOO 都是被匯出的名稱。名稱 foo 是不會被匯出的。
//執行程式碼。然後將 math.pi 改名為 math.Pi 再試著執行一下
func main() {
  fmt.Println(math.Pi)
}

函式

函式宣告將識別符號func繫結到函式。


package main
​
import ("fmt" "unsafe")
​
​
//函式可以返回一個或者多個值,具體看add和multipl函式
//兩個或多個連續的函式命名引數是同一型別,可以只需要最後一個引數定義型別
//Go 的返回值可以被命名,並且像變數那樣使用。
//返回值的名稱應當具有一定的意義,可以作為文件使用
//沒有引數的 return 語句返回結果的當前值。也就是`直接`返回
func add(x int, y int)(int){
  return x+y
}func multiple(x , y int)(string ,int){
  return "hello",x
}
​
​
func multiple2(x , y int)(str string ,z int){
  str="hello"
  z=x
  return
}//外部實現,這裡其實可以不定義結構體
//後續補充go:linkname
func FlushICache(begin,end int)
​
​
​
func main() {
  x ,y :=multiple(42, 13)
  fmt.Print(x,y)}

申明變數和常量

申明變數可以通過var或者:= 常量使用const


package main
​
import "fmt"
​
​
//go當中宣告一個變數可以通過var或者:=
//var可以作用在函式中也可以函式外
//:=只可以在函式中
//go有自動型別推斷,如果有初始值,可以不帶上變數型別
​
​
var initname="allen"
​
​
var name ,motherland  stringvar defaultvar string
//常量的定義和變數類似,只是換成了const來申明
const Pi = 3.14
func main()  {
  var num int
  age:=18
​
​
  fmt.Println(defaultvar,num,age)}

基本資料型別

package main
​
import (
  "math/cmplx"
  "fmt"
)/*
bool
​
string
​
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr
​
//一般需要用多大的可以選擇多大的數字型別
//如果沒有選擇將會按照作業系統選擇
//比如64位就會走int64
​
​
//go語言中的基礎資料型別都有預設值,
//這很正常引用指標得指向一個記憶體空間,才算初始化了一個變數
//否則一個指標不初始化,很容易造成基礎資料型別空指標。。。有點尷尬
​
byte // uint8 的別名
​
rune // int32 的別名,因為unicode是動態的所以選擇32位可以完全滿足,
    新版本java對於這一塊做了自動判斷,節省空間
​
​
float32 float64
​
complex64 complex128
 */
var (
  ToBe   bool       = false
  MaxInt uint64     = 1<<64 - 1
  z      complex128 = cmplx.Sqrt(-5 + 12i)
)func main() {
  const f = "%T(%v)\n"
  fmt.Printf(f, ToBe, ToBe)
  fmt.Printf(f, MaxInt, MaxInt)
  fmt.Printf(f, z, z)
}

流程控制語句

這部分沒有全部列出來只是舉了幾個典型例子以及常用的說明,具體可以看官網


for

for的用法和java中基本一樣,並且go裡面是沒有while了的


package main
​
import "fmt"
​
​
//for的使用和java中基本是一樣的,只是少了一個()
//並且go當中沒有while,使用for實現
//java中Doug Lea很喜歡這種寫法
func main() {
  sum := 0
  for i := 0; i < 10; i++ {
    sum += i
  }
  fmt.Println(sum)
​
  i := 1
  for i < 1000 {
    i += i
  }
  fmt.Println(i)for {
    break
  }
}

switch

switch的變化比較多,沒有條件的 switch 同 switchtrue一樣。這一構造使得可以用更清晰的形式來編寫長的 if-then-else 鏈 switch用法比java更方便靈活,不用顯示的在語句中加break 如果要實現類似java的一個case成立繼續執行後續的case可以使用fallthrough


package main
​
import (
  "fmt"
  "runtime"
  "time"
)
​
​
//switch用法比java更方便靈活,不用顯示的在語句中加break
//如果要實現類似java的一個case成立繼續執行後續的case可以使用fallthrough
//case也可以直接使用判斷語句//以及type switch//todo 後續看一下switch的實現原始碼
//感覺java的swtich語法糖和go比起來還是較弱,這也是java的歷史原因
func main() {
  fmt.Print("Go runs on ")
  switch os := runtime.GOOS; os {
  case "darwin":
    fmt.Println("OS X.")
    //fallthrough 開啟註釋看看結果
  case "linux":
    fmt.Println("Linux.")
    //fallthrough
  default:
    // freebsd, openbsd,
    // plan9, windows...
    fmt.Printf("%s.", os)
  }
​
​
  t := time.Now()
  switch {
  case t.Hour() < 12:
    fmt.Println("Good morning!")
  case t.Hour() < 17:
    fmt.Println("Good afternoon.")
  default:
    fmt.Println("Good evening.")
  }
​
​
  var a interface{}
​
  a = "abc"
​
​
​
  switch t := a.(type) {case string:
​
    fmt.Printf("string %s\n", t)case int:
​
    fmt.Printf("int %d\n", t)default:
​
    fmt.Printf("unexpected type %T", t)}}

defer

defer 語句會延遲函式的執行直到上層函式返回。延遲呼叫的引數會立刻生成,但是在上層函式返回前函式都不會被呼叫 可以理解為先進後出

package main
​
import (
  "fmt"
)//defer的操作其實是一個壓棧的方式呼叫
//先進後出FILO
//可以一次執行下面的三個例子//另外通過例子3其實可以知道defer是有資料拷貝的
//換句話說執行defer的時候資料就儲存了一個份
//後續變數怎麼改變defer還是輸出同樣的資訊//TODO defer的使用場景後續補充,暫時先當try catch finally使用
​
​
func main() {
  fmt.Println("counting")
​
  a:="hello world"for i := 0; i < 10; i++ {
    defer fmt.Println(i)
  }
​
  fmt.Println("done")
  //1.os.Exit(0)//直接推出不會執行defer
  //2.return//遇到return才返回
  defer fmt.Println(a)
  //3.a="hello defer"
  fmt.Println("done")//沒有return則執行到底
}

最後各位可以掃下方二維碼關注我公眾號,基本每週會推送一到兩篇的go學習記錄,後續學完基礎語法,會準備寫一個go微服務專案,原始碼依然放在github上面。

avatar

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章