如何優雅的入門golang

deliangyang發表於2018-06-22

golang

golang標準庫文件

特色

  • 簡單、快速、安全
  • 並行、有趣、開源
  • 記憶體管理、v陣列安全、編譯迅速

高效能分散式系統開發、海量並行處理、遊戲服務端開發再好不過了

一個go程式

package main

import "fmt"

func main() {
    fmt.println("hello world!")
}
複製程式碼
$ go run main.go
hello world!
複製程式碼

基礎組成

  • 包宣告 package
  • 引入包 import
  • 函式 func
  • 變數 var
  • 語句 & 表示式
  • 註釋 不會被編譯
    • // 單行註釋
    • /* */ 多行註釋

識別符號

識別符號用來命名變數、型別等程式體。一個或者多個字母[a-zA-Z]、數字[0-9]、下劃線_組成, 但是第一個字元必須為_或者字母

  • 有效

    • hello、krc、j、_a、a123、retVal
  • 無效

    • 1abc (首字母不能為數字)、case (關鍵詞)、a+b (出現非約束字元)

關鍵詞

型別 型別 型別 型別 型別
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

預定義

型別 型別 型別 型別 型別 型別 型別 型別 型別
append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr

golang中資料型別

  • 布林型別 true or false
var b bool = true
var c bool = false
複製程式碼
  • 數字型別

整型 int、浮點型 float32、float64,原生支援複數,其中位的運算採用補碼

型別 型別 型別 型別
uint8 uint16 uint32 uint64
int8 int16 int32 int64
float32 float64 complex64 complex128
byte rune uint int
uintptr
  • 字串型別

使用utf-8編碼標識unicode文字

  • 派生型別

    • 指標型別 Pointer
    • 陣列型別
    • 結構化型別 struct
    • Channel型別
    • 函式型別
    • 切片型別
    • 介面型別 interface
    • Map 型別
var a = "世界你好"
var b string = "hello world"
var c bool

複製程式碼

不帶宣告的只能在函式中體現

package main

var x, y int
var (  // 這種因式分解關鍵字的寫法一般用於宣告全域性變數
    a int
    b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//這種不帶宣告格式的只能在函式體中出現
//g, h := 123, "hello"

func main(){
    g, h := 123, "hello"
    println(x, y, a, b, c, d, e, f, g, h)
}

複製程式碼

函式定義

func function_name( [parameter list] ) [return_types] {
   函式體
}
複製程式碼

陣列定義

var var_name [size] var_type

var blance [10] float32

// 初始化陣列

var blance = [10]int {1,2,3,4,5,6,7,8,9,10}
複製程式碼

指標

指標變數是指向一個值得記憶體地址 類似於變數和常量,在使用指標變數前也需要宣告這個指標

var ip *int

var fp *float32

var a int = 32

ip = &a            
fmt.Printf("a 變數的地址是: %x\n", &a) // 指標的地址

fmt.Printf("*ip 變數的值: %d\n", *ip) // 指標的值

var var_name *var_type
複製程式碼

空指標

當一個指標被定義之後沒有賦值的話,它的值為nil nil指標也稱為空指標

結構體

// 定義一個結構體
type struct_var_type struct {
    member definition;
    member definition;
    member definition;
    member definition;
}

// 宣告結構體

var_name := struct_var_type {var1, var2, var3}


type Books struct {
   title string
   author string
   subject string
   book_id int
}

// 宣告 Book1 為 Books 型別
var Book1 Books       

Book1.title = "Go 語言"
Book1.author = "ydl"
Book1.subject = "Go語言學習"
Book1.book_id = 123

// 列印這個結構體
fmt.Printf( "Book 1 title : %s\n", Book1.title)
fmt.Printf( "Book 1 author : %s\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

func printBook(book Books) {
    fmt.Printf( "Book 1 title : %s\n", book.title)
    fmt.Printf( "Book 1 author : %s\n", book.author)
    fmt.Printf( "Book 1 subject : %s\n", book.subject)
    fmt.Printf( "Book 1 book_id : %d\n", book.book_id)
}

// 結構體指標

var struct_pointer *Books

struct_pointer = &Book1

複製程式碼

切片

宣告一個未定義長度的陣列

var var_name [] var_type
複製程式碼

或者使用 make()來建立一個切片

var slice1 []type = make([]type, len)

// or

slice1 := make([]type, len)

// 初始化

slice1 :=[] int {1,2,3 } 

複製程式碼

類似於python中的切片,取值

s := slice1[start:]
s := slice1[start:end]
s := slice1[:end]
複製程式碼

相關函式介紹

len() 獲取長度 cap() 測量切片最長長度可以到達多少 append() 追加 copy() 拷貝切片

空切片

未初始化的切片,為nil,長度為0

語言範圍 range

range 用於for迴圈中迭代陣列array、切片slice、通道channel、集合map等元素

Map集合

  • 無序的鍵值對
  • 可以像陣列和切片一樣迭代
  • 使用hash實現的

定義一個map集合

var map_var_name map[key_data_type] var_type

// 使用make函式
map_var := make(map[key_data_type]var_type)


複製程式碼

型別轉換

type_name(express)

go 介面型別

把所有具有共性的方法放置在一起,任何其他型別只需要實現這些方法就實現了這個介面

/* 定義介面 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定義結構體 */
type struct_name struct {
   /* variables */
}

/* 實現介面方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法實現 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法實現*/
}
複製程式碼

錯誤處理


errors.New("math: square root of negative number")
複製程式碼

感想

  • 其實語言還是有很多的通性的,在資料型別和流程控制方面有些差異,但是大致還是一個方向,可能資料型別更豐富了,流程控制更加的方便等 在語言方面增加了很多的特性,使得這個語言解決一些特定的場景需求,比如海量併發、高效能等

  • go 的發展很迅速,開源的庫也很多,也有很多出名的開源專案,如:docker容器、TiDB資料庫、k8s(Kubernetes)容器編排技術

  • go的社群也比較活躍,在一些一線城市需求量比較大,高效能web服務,遊戲後端開發等等

  • 其實我自己開始學php開發的,開發一些web和後端api專案,對於我來說如果再學一些go的web開發,感覺對我的幫助不大,瞭解自身薄弱之處:

    • 資料結構和演算法
    • 網路程式設計
    • 非同步、同步、io操作
    • 設計模式
    • 多執行緒
    • 資料庫
  • 其實程式設計千變萬化不離其中,離不開基礎,而這些都是建築高樓大廈的基礎,很多人在開發過程中會遇到瓶頸,不知道如何提升,其實我們可以再次複習以前學過的知識, 溫故而知新,讀一本書我們可以瞭解到這本書講的是什麼,第二次讀我們可以讀到更多,作者寫作意圖,融入作者的思維,跟隨作者置身其中,得到不一樣的感受。開發學習亦是如此, 多學習幾遍基礎,我們會有不一樣的感受,視野也會更加的廣闊,切勿浮躁,走馬觀花。熱門的框架學習固然重要,跟隨時代的潮流,不落伍。但是學習框架也是有跡可循的,在後面我會 介紹如何去學一個框架,入門一個框架,原始碼分析,思維導圖等等。

相關文章