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