前言
最近看完了兩本golang的書砾嫉,也使用golang搭建了一個框架幼苛,寫了一個物聯(lián)網(wǎng)項目
所以來做個入門總結(jié)
關(guān)鍵字
golang 一共有25個關(guān)鍵字 ,不能用作標識符焕刮,分成三大類舶沿,程序包管理、實體聲明和定義配并、流程控制
如果有其它語言基礎(chǔ)括荡,大部分都可以知道其功能
程序包管理:
package
package用于聲明包的名稱,需放在go文件所有代碼的最前面溉旋。一個包由一個或多個go源文件組成畸冲,需放在同一個目錄下,且同一個目錄下的這些go文件的package的名字只能有一個
import 包引入
其中包路徑前面可以有三中修飾符中的某一個 [ _ . alias ]
package <packagename>
import _ "package path"
import . "package path"
import alias "package path"
import (
_ "package path"
. "package path"
alias "package path"
)
實體聲明和定義
var
定義變量
var name T //name默認為類型T的零值
var name = value //根據(jù)值value推斷變量name的類型
var name T = value //賦初始值時指明類型
var name1, name2 T //同時定義多個同類型變量
//同時定義多個不同類型的變量
var (
name string ="dable"
age int = 18
)
//最簡單用法,也是最常用法
name := value
const 常量
同 var
func 函數(shù)和方法
func 用于定義函數(shù)邑闲,Go函數(shù)支持變參且返回值支持多個算行。
func funcName(){} //無參無返回值
func funcName(t T) T {} //有參有返回值
func funcName(t T, list ...T) (T1,T1) {} //有變參有多個返回值
func (s struct) funcName() {} //可以帶結(jié)構(gòu)體
type 類型
type 用于定義類型,比如定義struct苫耸、interface等類型
struct 結(jié)構(gòu)體
struct 用于定義結(jié)構(gòu)體
type Name struct {
X, Y int
}
interface 接口
interface 用于定義接口州邢。一個接口是一個方法集,如果一個類型實現(xiàn)了一個接口中的所有方法集鲸阔,那么說明該類型實現(xiàn)此接口偷霉。接口類型變量可以存儲任何實現(xiàn)了該接口的類型的值迄委。特別的褐筛,interface{}表示空接口類型,默認地叙身,所有類型均實現(xiàn)了空接口渔扎,所以interface{}可以接收任意類型值。
//空接口
interface{}
//Person接口
type Person interface {
Walk()
Run()
Say(s string)
}
map 字典
map 用于聲明映射變量信轿。映射屬容器類類型晃痴,是一個同種類型元素的無序組,通過唯一的鍵可以獲取對應(yīng)的值财忽√群耍可以使用 make 創(chuàng)建 map 變量,未初始化的映射值為 nil即彪。創(chuàng)建map變量主要有如下幾種方式:
//創(chuàng)建0容量的map
var map1 = make(map[T1] T2)
//創(chuàng)建指定容量的map紧唱,只是初始容量,會自動擴容
var map2 = make(map[T]T2, 10)
//創(chuàng)建并初始化map
var map3 = map[string]int {
"k1" : 1,
"k2" : 2,
}
// 創(chuàng)建可以放任意值的map
var map4 = make(map[string]interface{})
chan 管道
chan用于聲明channel(信道)隶校。信道提供一種機制使兩個并發(fā)執(zhí)行的函數(shù)實現(xiàn)同步漏益,并通過傳遞具體元素類型的值來通信。未初始化的信道值為 nil深胳。聲明格式如下:
//定義chan類型變量
var ch chan int = make(chan int, 10);
//或者
ch := make(chan int, 10);
//給chan寫數(shù)據(jù)
ch <- 1;
ch <- 2;
//從chan 讀數(shù)據(jù)
var x int;
x = <-ch;
其中<-操作符指定信道的方向绰疤,發(fā)送或接收。若沒有給定方向舞终,那么該信道就是雙向的轻庆。信道可通過類型轉(zhuǎn)換或賦值被強制為只發(fā)送或只接收。
信道的初始化可以通過 make 函數(shù)來實現(xiàn)敛劝,其結(jié)果值充當了對底層數(shù)據(jù)結(jié)構(gòu)的引用榨了。初始化時可以為信道設(shè)置緩沖區(qū)大小,默認值是零攘蔽,表示不帶緩沖的或同步的信道
ci := make(chan int) // 整數(shù)類型的無緩沖信道
cj := make(chan int, 0) // 整數(shù)類型的無緩沖信道
cp := make(chan *os.File, 100) // 指向文件指針的帶緩沖信道
流程控制
go 多線程
go用于創(chuàng)建Go線程(goroutine)龙屉,實現(xiàn)并發(fā)編程。Go程是與其它Go程并發(fā)運行在同一地址空間的函數(shù),相比于線程與進程转捕,它是輕量級的作岖。Go程在多線程操作系統(tǒng)上可實現(xiàn)多路復(fù)用,因此若一個線程阻塞五芝,比如說等待I/O痘儡,那么其它的線程就會運行。Go程的設(shè)計隱藏了線程創(chuàng)建和管理的諸多復(fù)雜性枢步。
在函數(shù)或方法前添加 go 關(guān)鍵字能夠在新的Go程中調(diào)用它沉删。當調(diào)用完成后,該Go程也會安靜地退出醉途。效果有點像Unix Shell中的 & 符號矾瑰,它能讓命令在后臺運行。
//并發(fā)執(zhí)行
go func()
select
select 是 Go 中的一個控制結(jié)構(gòu)隘擎,類似于用于通信的 switch 語句殴穴。每個 case 必須是一個通信操作,要么是發(fā)送要么是接收货葬。select 隨機執(zhí)行一個可運行的 case采幌。如果沒有 case 可運行,它將阻塞震桶,直到有 case 可運行
Go 編程語言中 select 語句的語法如下:
select {
case communication clause :
statement(s);
case communication clause :
statement(s);
/* 你可以定義任意數(shù)量的 case */
default : /* 可選 */
statement(s);
}
for 循環(huán)
for是Go中唯一用于循環(huán)結(jié)構(gòu)的關(guān)鍵詞休傍。有三個使用方式,分別是單個循環(huán)條件蹲姐,經(jīng)典的初始化/條件/后續(xù)形式磨取,還有和range關(guān)鍵詞結(jié)合使用來遍歷容器類對象(數(shù)組、切片淤堵、映射)寝衫。
//單條件
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}
//初始化/條件/后續(xù)形式
//注意Go中沒有前置自增與自減運算符,即++i是非法的
for i:=0; i < 3; i++ {
fmt.Println(i)
}
//for range形式遍歷數(shù)組
array :=[...]int{0,1,2,3,4,5}
for i, v :=range array{
fmt.Println(i,v)
}
range 迭代器
同 for 一起使用拐邪,遍歷對象↑
break
break用于終止最內(nèi)層的"for"慰毅、“switch"或"select"語句的執(zhí)行。
continue
結(jié)合for一起使用扎阶,continue通常用于結(jié)束當前循環(huán)
if else
條件判斷語句
- 可省略條件表達式的括號汹胃;
- 支持初始化語句,可定義代碼塊局部變量东臀;
- if與else塊中只有一條語句也需要添加大括號着饥;
- 起始大括號必須與if與else同行。
if 布爾表達式 {
/* 在布爾表達式為 true 時執(zhí)行 */
} else{
/* 在布爾表達式為 false 時執(zhí)行 */
}
//支持多個else if
if 表達式1 {
// 符合表達式1執(zhí)行
} else if 表達式2 {
// 符合表達式2 執(zhí)行
} else {
// 沒有符合的表達式執(zhí)行
}
// 可以聲明變量
if bool := true;bool {
//執(zhí)行
}
switch case default fallthrough
這四個關(guān)鍵字是結(jié)合使用的惰赋,switch語句提供多路執(zhí)行宰掉,表達式或類型說明符與switch中的case相比較從而決定執(zhí)行哪一分支呵哨。default用于給出默認分支,即所有的case分支都不滿足時執(zhí)行default分支轨奄。Go中的switch語句在執(zhí)行完某個case子句后孟害,不會再順序地執(zhí)行后面的case子句,而是結(jié)束當前switch語句挪拟。使用fallthrough可以繼續(xù)執(zhí)行后面的case與default子句挨务。
//表達式選擇
switch tag {
default: s3() //default子句可以出現(xiàn)在switch語句中的任意位置,不一定是最后一個
case 0, 1, 2, 3: s1() //case表達式可以提供多個待匹配的值玉组,使用逗號分隔
case 4, 5, 6, 7: s2()
}
switch x := f(); {
case x < 0: return -x //case表達式無需為常量
default: return x
}
switch { //缺失的switch表達式意為"true"
case x < y: f1()
fallthrough //強制執(zhí)行下一個case子句
case x < z: f2()
//此處沒有fallthrough谎柄,switch執(zhí)行流在此終止
case x == 4: f3()
}
//類型選擇
switch i := x.(type) {
case int:
printInt(i) // i 的類型為 int
case float64:
printFloat64(i) // i 的類型為 float64
case func(int) float64:
printFunction(i) // i 的類型為 func(int) float64
case bool, string:
printString("type is bool or string") // i 的類型為 bool or string
default:
printString("don't know the type") // i 的類型未知
}
defer
defer語句用于預(yù)設(shè)一個函數(shù)調(diào)用,即推遲函數(shù)的執(zhí)行惯雳。 該函數(shù)會在執(zhí)行 defer 的函數(shù)返回之前立即執(zhí)行朝巫。它顯得非比尋常, 但卻是處理一些事情的有效方式吨凑,例如無論以何種路徑返回捍歪,都必須釋放資源的函數(shù)户辱。 典型的例子就是解鎖互斥和關(guān)閉文件鸵钝。如果有多個defer 按照倒序執(zhí)行。
//將文件的內(nèi)容作為字符串返回庐镐。
func Contents(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close() // f.Close 會在函數(shù)結(jié)束后運行
var result []byte
buf := make([]byte, 100)
for {
n, err := f.Read(buf[0:])
result = append(result, buf[0:n]...)
if err != nil {
if err == io.EOF {
break
}
return "", err // 我們在這里返回后恩商,f 就會被關(guān)閉
}
}
return string(result), nil // 我們在這里返回后,f 就會被關(guān)閉
}
goto
goto用于將程序的執(zhí)行轉(zhuǎn)移到與其標簽相應(yīng)的語句必逆〉】埃可以使用goto退出多層"for"、“switch"或"select”名眉,功能類似于break攜帶標簽粟矿。
//終止for
L:
for i < n {
n++
goto L
}
return
return用于函數(shù)執(zhí)行的終止并可選地提供一個或多個返回值。 任何在函數(shù)F中被推遲的函數(shù)會在F 返回給其調(diào)用者前執(zhí)行损拢。函數(shù)可以通過return返回多個值陌粹。如果返回值在函數(shù)返回形參中指定了名字,那么return時可不帶返回值列表福压。
//無返回值
func noResult() {
return
}
//單返回值
func f1() int {
return 2
}
//多返回值
func f2() (float64, float64) {
re = 7.0
im = 4.0
return re, im
}
//返回值已具名
unc f3() (re float64, im float64) {
re = 7.0
im = 4.0
return
}
參考: