Go學習 Go語言優勢 可直接編譯成機器碼,不依賴其他庫。 靜態類型語言 語言層面支持併發 內置runtime,支持垃圾回收 簡單易學,Go語言的作者都有C的基因,那麼Go自然而然就有了C的基因,那麼Go關鍵字是25個,但是表達能力很強大,幾乎支持大多數其他語言見過的特性:繼承、重載、對象等 豐富的 ...
Go學習
Go語言優勢
- 可直接編譯成機器碼,不依賴其他庫。
- 靜態類型語言
- 語言層面支持併發
- 內置runtime,支持垃圾回收
- 簡單易學,Go語言的作者都有C的基因,那麼Go自然而然就有了C的基因,那麼Go關鍵字是25個,但是表達能力很強大,幾乎支持大多數其他語言見過的特性:繼承、重載、對象等
- 豐富的標準庫
- 內置強大的工具,Go語言裡面內置了很多工具鏈,最好的應該是gofmt工具,自動化格式化代碼,能夠讓團隊review變得如此的簡單,代碼格式一模一樣,想不一樣都很困難。
- 跨平臺編譯
內嵌C支持,Go裡面也可以直接包含C代碼,利用現有的豐富的C庫。
Go適合用來做什麼
- 伺服器編程
- 分散式系統,資料庫代理器
- 網路編程
記憶體資料庫
標準命令概述
- build:用於編譯給定的代碼包或Go語言源碼文件及其依賴包。
- clean:用於清除執行其他Go命令後遺留的目錄和文件。
- doc:用於執行godoc命令以列印指定代碼包。
- env:用於列印go語言環境信息
- fix:用於執行gotoo fix命令以修正給定代碼包的源碼文件中包含的過時語法和代碼調用。
- fmt:用於執行gofmt命令以格式化給定代碼包中的源碼文件。
- get:用於下載和安裝給定代碼包及其依賴包
- list:用於顯示給定代碼包的信息。
- run:用於編譯並運行給定的命令源碼文件。
- install:編譯包文件並編譯整個程式。
- test:用於測試給定的代碼包。
- tool:用於運行Go語言的特殊工具。
version:用於顯示當前安裝的Go語言的版本信息。
第一個Go程式
package main
import (
"fmt"
)
func main(){
fmt.Println("hello world")
}
關鍵字
- 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
內建常量:
true false iota nil
內建類型:int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string error
內建函數:make len cap new append copy close delete complex real imag panic recover
變數
var v1 int
var v2 int
//一次定義多個變數
var v3,v4,v5 int
var (
v10 int
v11 int
)
var v1 int = 10
var v2 = 10
v3 := 10
var v11,v22,v23 = 1, 2, 3
基礎數據類型
類型 | 名稱 | 長度 | 零值 | 說明 |
---|---|---|---|---|
bool | 布爾類型 | 1 | false | 其值不為真就是假,不可以用數字代表true或false |
byte | 位元組型 | 1 | 0 | uint8別名 |
rune | 字元類型 | 4 | 0 | 專用於存儲unicode編碼,等價於uint32 |
int,uint | 整型 | 4或8 | 0 | 32位或64位 |
int8,uint8 | 整型 | 1 | 0 | -128~127,0~255 |
int16,uint16 | 整型 | 2 | 0 | -32768~32767,0~65535 |
int32,uint32 | 整型 | 4 | 0 | -21億~21億,0~42億 |
int64,uint64 | 整型 | 8 | 0 | |
float32 | 浮點型 | 4 | 0.0 | 小數位精確到7位 |
float64 | 浮點型 | 8 | 0.0 | 小數位精確到15位 |
complex64複數類型 | 8 | |||
complex128複數類型 | 16 | |||
uintptr整型 | 4或8 | 以存儲指針的uint32或uint64整數 | ||
string | 字元串 | "" | utf-8字元串 |
使用fmt包來格式化字元串
fmt.Printf()格式字元串:
|列印格式|含義|
|---|---|
|%%|一個%字面量|
|%b|一個二進位整數值(基數為2),或者是一個用科學計數法表示的指數為2的浮點數|
|%c|字元型。可以把輸入的數字按照ASCII碼相應轉換位對應的字元|
|%e|以科學技術法e表示的浮點數或者複數值|
|%E|以科學計數法E表示的浮點數或者複數值|
|%f|以標準計數法表示的浮點數或者複數值|
|%g|以%e或者%f表示的浮點數或者複數,任何一個以最為緊湊的方式輸出|
|%G|以%E或者%f表示的浮點數或者複數,任何一個都以最為緊湊的方式輸出|
|%o|一個以八進位表示的數字(基數為8)|
|%p|以十六進位(基數為16)表示的一個值的地址,首碼為0x,字母使用小寫的a-f表示|
|%T|使用Go語法輸出的值的類型|
類型轉換
Go語言中不允許隱式轉換,所有類型轉換必須顯示聲明,而且轉換隻能發生在兩種相互相容的類型之間。
var ch byte = 97
var a int = int(ch)
類型別名
type bigint int64 // int64類型改名為bigint
var x bigint = 100
type (
myint int
mystr string
)
流程式控制制
Go語言支持最基本的三種程式運行結構:順序結構、選擇結構、迴圈結構。
if語句
if
var a int = 3
if a == 3{
fmt.Println("a==3")
}
//支持一個初始化表達式,初始化子句和條件表達式直接需要用分號分隔
if b := 3; b == 3{
fmt.Println("b == 3")
}
if...else
if a := 3; a == 4{
}else{
fmt.Println("a != 4")
}
switch語句
Go裡面switch預設相當於每個case最後帶有break,匹配成功後不會自動向下執行其他case,而是跳出整個switch,但是可以使用fallthrough強制執行後面的case代碼:
var score int = 90
switch score{
case 10:
fmt.Println("游戲")
case 80:
fmt.Println("靚號")
default:
fmt.Println("差")
}
可以使用任何類型或表達式作為條件語句:
switch s1 := 90; s1{
case 90:
fmt.Println("優秀")
default:
fmt.Println("一般")
}
var s2 int = 90
switch {
case s2 >= 90:
fmt.Println("優秀")
case s2 >=80
fmt.Println("發的")
}
迴圈語句
for
var i, sum int
for i = 1; i <= 100; i++{
sum += i
}
fmt.Println("sum =", sum)
range
s := "abc"
for i := range s{
fmt.Printf("%c\n", s[i])
}
for _, c := range s{
fmt.Println("%c\n", c)
}
跳轉語句
break和continue
for i := 0; i < 100; i++{
if 2 == i{
continue
}
}
goto
func main(){
LABEL:
for i := 0; i < 100; i++{
for {
fmt.Println(i)
goto LABEL
}
}
}
自定義格式
Go語言函數定義格式:
func FuncName(/*參數列表*/) (o1 type1, o2 type2/*返回類型*/){
//函數體
return v1, v2
}
延遲調用defer
defer作用
關鍵字defer用於延遲一個函數或者方法的執行
func main(){
fmt.Println("this is a test")
defer fmt.Println("this is a defer")
}
多個defer執行順序
如果一個函數中多個defer語句,他們會以LIFO(後進先出)的順序執行。哪怕函數或某個延遲調用發生錯誤,這些調用依舊會被執行。
獲取命令行參數
package main
import (
"fmt"
"os"
)
func main(){
args := os.Args
if args == nil || len(args) < 2{
fmt.Println("err:xxx ip port")
return
}
ip := args[1]
port := args[2]
}
複合類型
類型 | 名稱 | 長度 | 預設值 | 說明 |
---|---|---|---|---|
pointer | 指針 | nil | ||
array | 數組 | 0 | ||
slice | 切片 | nil | 引用類型 | |
map | 字典 | n | nil | 引用類型 |
struct | 結構體 |
複合類型-指針
- 預設值nil,沒有NULL常量
- 操作符“&”取變數地址,"*"通過指針訪問目標對象
- 不支持指針運算,不支持"->"運算符,直接用"."訪問目標成員
package main
import (
"fmt"
)
func main(){
var a int = 10
fmt.Printf("&a = %p", &a)
var p *int = nil
p = &a
fmt.Printf("p = %p\n", p)
fmt.Printf("a = %d,*p = %d\n", a, *p)
*p = 111
fmt.Printf("a = %d, *p = %d\n", a, *p)
}
new函數
表達式new(T)將創建一個T類型的匿名變數,所做的是為T類型的新值分配並清零一塊記憶體空間,然後將這塊記憶體空間的地址作為結果返回,而這個結果就是指向這個新的T類型值的指針值,返回的指針類型為*T.
package main
import (
"fmt"
)
func main(){
var p1 *int
p1 = new(int)
fmt.Println("*p1 = ", *p1)
p2 := new(int)
*p2 = 111
fmt.Println("*p2 = ", *p2)
}
符合類型-數組
數組是指一系列同一類型數據的集合。數組中包含的每個數據被稱為數組元素,一個數組包含的元素個數被稱為數組的長度。
數組長度必須是常量,且是類型的組成部分。[2]int 和 [4]int是不同類型。
操作數組
數組的每個元素可以通過索引下標來訪問,索引下標的範圍是從0開始到數組長度減1的位置。
package main
import (
"fmt"
)
func main(){
var a [10] int
for i := 0; i < 10; i++{
a[i] = i + 1
fmt.Println(i, a[i])
}
for i, v := range a{
fmt.Println(i, v)
}
}
內置函數len和cap都返回數組長度
fmt.Println(len(a), cap(a))