變量 var
- 關(guān)鍵字是 var ,定義后須被調(diào)用
- 支持多個(gè)同時(shí)定義
- 支持使用 := 缺省定義
變量定義(聲明)
//使用var 關(guān)鍵字 進(jìn)行變量定義 : var + 變量名 + 變量類(lèi)型
//Var name type
var aa int = 10
//var name 省略類(lèi)型
var aa = 10
// 多個(gè)進(jìn)行定義,也可省略類(lèi)型
var Mon, Tues, Wed, Thur, Fri, Sat, Sun int
var (
Monday int
Tuesday int
Wednesday int
Thursday int
Friday int
Saturday int
Sunday int
)
// 使用 := 快捷定義,但":=" 結(jié)構(gòu)不能在函數(shù)外使用
var aa := 10
//多個(gè)定義
aa, bb :=10, '10'
//聲明但可不使用
aa,_ := 10, '10'
變量調(diào)用
//變量調(diào)用分為 局部變量 和 全局變量
package main
//import
import (
"fmt"
)
//全局變量定義 aa ss
var (
aa = 3
ss = "kkk"
)
//局部變量定義
func variableZeroValue() {
var a int
var s string
//fmt.Println(a, s)
fmt.Printf("%d %q \n", a, s)
}
func main() {
//fmt.Println("helloworld")
variableZeroValue()
}
常量 const
- 關(guān)鍵字為 const, 可不被調(diào)用
- 枚舉類(lèi)型 iota
- 常量不可改變
常量定義
//const name type
//const name
//:=
//多常量
const(
aa = 1
bb =2
)
//使用iota, 從0開(kāi)始,iota 自增被打斷,須顯式恢復(fù)
const (
b = 1 << (10 * iota)
kb
mb
gb
)
常量調(diào)用
- 常量使用與變量相似 ,故不贅述
- 與c語(yǔ)言不同,常量不能通過(guò)指針進(jìn)行強(qiáng)制更改
數(shù)組 arr
- 在Go語(yǔ)言中數(shù)組是固定長(zhǎng)度的數(shù)據(jù)類(lèi)型,它包含相同類(lèi)型的連續(xù)的元素,這些元素可以是內(nèi)建類(lèi)型,像數(shù)字和字符串,也可以是結(jié)構(gòu)類(lèi)型,元素可以通過(guò)唯一的索引值訪問(wèn),從0開(kāi)始。
- 使用 var 關(guān)鍵字
數(shù)組定義
//定義 長(zhǎng)度是5的arr
var arr [5]int
//定義并初始化
var arr [5]int = [5]int{1,2,3,4,5}
//快速定義
arr := [5]int{1,2,3,4,5}
//不知長(zhǎng)度
arr := [...]int{1,2,3,4}
//部分初始化, 其他位置初始化為0
arr := [5]int{1:1,3:4}
調(diào)用
package main
import "fmt"
func main() {
array := [2]int{}
fmt.Printf("數(shù)組長(zhǎng)度:%d,數(shù)組容量:%d\n", len(array), cap(array))
}
//數(shù)組長(zhǎng)度:2,數(shù)組容量:2
切片 Slice
- "動(dòng)態(tài)數(shù)組" ,長(zhǎng)度不固定,可以追加 append (name, 5)
- 通過(guò)內(nèi)部指針和相關(guān)屬性應(yīng)用數(shù)組片段
- type, len, cap 為Slice三個(gè)屬性, 如果slice == nil 則len,cap均為零
定義
//定義一個(gè)切片,不用大小
var name []int
//定義并初始化
var aa []int = []int{1,2,3}
var bb = []int{1,2,3}
//通過(guò)內(nèi)置函數(shù)make 進(jìn)行定義 make (type, len, cap)
var aa []int = make([]int, 3)
var aa = make([]int, 3)
var aa = make([]int, 3, 3)
aa := make([]int, 3)
//通過(guò)切數(shù)組得到 arr := [5]int{1,2,3,4,5}
aa := arr[:len(arr)-1]
調(diào)用
切片拷貝,使用copy() 函數(shù) copy 在兩個(gè) slice 間復(fù)制數(shù)據(jù),復(fù)制長(zhǎng)度以 len 小的為準(zhǔn)。兩個(gè) slice 可指向同一底層數(shù)組,允許元素區(qū)間重疊。
package main
import "fmt"
func main() {
var a = []int{1, 2, 3, 4, 5}
b := []int{100, 200}
copy(a, b)
fmt.Println(a, b)
}
運(yùn)行結(jié)果:
[100 200 3 4 5] [100 200]
容器 Map
- key- value 表
- 無(wú)序,散列表hash完成
- 可使用內(nèi)置函數(shù)delete(m, "key"), 不可以在map上使用cap()方法。
定義
//聲明
var m map[int]string
//聲明并初始化
var m map[int]string {1;"1",2;'2'}
//通過(guò)make 創(chuàng)建
var m1 = make(map[int]string, 10)
m2 = make(map[int]string, 10)
調(diào)用
//增
m[3] = "3"
//刪,刪除操作,如果 key 不存在,不會(huì)出錯(cuò)
delete(m, "3")
//改
m[1] ='2'
//查
if _, ok = m[3]; ok{
fmt.Println("find it")
}
//長(zhǎng)
len := len(m)
管道 Channel
看成管道, 可單雙向使用, chan 定義
-
無(wú)緩沖的與有緩沖channel有著重大差別,那就是一個(gè)是同步的 一個(gè)是非同步的。 比如
無(wú)緩沖chan:ch1:=make(chan int)
有緩沖chan:ch2:=make(chan int,1)
無(wú)緩沖: ch1<-1 不僅僅是向 c1 通道放 1,而是一直要等有別的攜程 <-ch1 接手了這個(gè)參數(shù),那么ch1<-1才會(huì)繼續(xù)下去,要不然就一直阻塞著。
有緩沖: ch2<-1 則不會(huì)阻塞,因?yàn)榫彌_區(qū)大小是1(其實(shí)是緩沖大小為0),只有當(dāng)放第二個(gè)值的時(shí)候,第一個(gè)還沒(méi)被人拿走,這時(shí)候才會(huì)阻塞。
緩沖區(qū)是內(nèi)部屬性,并非類(lèi)型構(gòu)成要素。
普通 channel 可以隱式轉(zhuǎn)為只讀channel或只寫(xiě)channel,反過(guò)來(lái)則不行
內(nèi)置函數(shù) len() 返回未被讀取的緩沖元素?cái)?shù)量,使用內(nèi)置函數(shù) cap() 返回緩沖區(qū)大小
使用內(nèi)置函數(shù) close() 進(jìn)行關(guān)閉 chan,向已經(jīng)關(guān)閉的 channel 發(fā)送數(shù)據(jù)會(huì)引發(fā) panic 錯(cuò)誤。
定義
//使用chan 定義
var aa chan int
var aa chan string
var aa chan map[int]string
//make 定義
var aa = make(chan int) //無(wú)緩沖
var aa = make(chan int, 10) //有緩沖
//只讀
var aa <-chan int
var aa = make(<-chan int, 10)
//只寫(xiě)
var aa chan<- int
var aa = make(chan<-int, 10)
調(diào)用
//開(kāi)
var aa = make(chan int, 3)
//放
aa <- 1
//關(guān)
close(aa)
指針
- *(取值符) 來(lái)獲取指針?biāo)赶虻膬?nèi)容 , &(取地址符)來(lái)獲取該變量的指針。
- 不可加減乘除,Go語(yǔ)言是不允許兩個(gè)指針類(lèi)型進(jìn)行轉(zhuǎn)換的
- 空指針 nil
- unsafe.Pointer 類(lèi)型用于表示任意類(lèi)型的指針
定義
//使用var 進(jìn)行
var p *int
//使用:= 定義
var str string
p := &str
//指針變量的指針
var **p int
//time.Time (一個(gè)結(jié)構(gòu)體)值的指針
var t *time.Time
結(jié)構(gòu)體
結(jié)構(gòu)體是由一系列具有相同類(lèi)型或不同類(lèi)型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合。
struct 特點(diǎn)
1、用來(lái)自定義復(fù)雜數(shù)據(jù)結(jié)構(gòu)
2、struct里面可以包含一個(gè)或多個(gè)字段(屬性)
3、struct類(lèi)型可以定義方法,注意和函數(shù)的區(qū)分
4、struct類(lèi)型是值類(lèi)型
5、struct類(lèi)型可以嵌套
6、結(jié)構(gòu)體是用戶單獨(dú)定義的類(lèi)型,不能和其他類(lèi)型進(jìn)行強(qiáng)制轉(zhuǎn)換
7、Go中的struct沒(méi)有構(gòu)造函數(shù),一般可以使用工廠模式來(lái)解決這個(gè)問(wèn)題
8、我們可以為struct中的每個(gè)字段,寫(xiě)上一個(gè)tag。這個(gè)tag可以通過(guò)反射的機(jī)制獲取到,最常用的場(chǎng)景就是json序列化和反序列化
9、訪問(wèn)結(jié)構(gòu)體成員, 用 "." 來(lái)連接,格式為:"結(jié)構(gòu)體.成員名"
定義
//全局或函數(shù)內(nèi)定義類(lèi)型
type bight int64
//定義新類(lèi)型,不能同時(shí)嵌入某一類(lèi)型和其指針類(lèi)型(名字相同)
type moreType struct{
linux string
win string
debin string
}
type lin stuct{
*linux
}
//聲明struct結(jié)構(gòu)的時(shí)候,在屬性的右側(cè)用小米點(diǎn)括起來(lái)的內(nèi)容叫標(biāo)簽(Tag),在轉(zhuǎn)換成其它數(shù)據(jù)格式的時(shí)候,會(huì)使用其中特定的字段作為鍵值。例如轉(zhuǎn)成json格式
user := &User{UserId: 1, UserName: "helloworld"}
json_user, _ := json.Marshal(user)
fmt.Printf("struct User echo : %v\n", string(json_user))
user_tag := &UserTag{UserId: 1, UserName: "helloworld"}
json_user_tag, _ := json.Marshal(user_tag)
fmt.Printf("struct UserTag echo : %v\n", string(json_user_tag))
函數(shù)
定義
//無(wú)參數(shù)
func funName(){
}
//有參數(shù)
func funName(x, y int){
}
//一返回值
func funName(x, y int) int{
}
//多返回
fun funNmame(x,y int)(ret int, err error){
}
//只有類(lèi)型
fun funNmame(int, int)(int, error){
}
1、Go語(yǔ)言函數(shù)中的參數(shù)不支持默認(rèn)值。
2、無(wú)論是值傳遞,還是引用傳遞,傳遞給函數(shù)的都是變量的副本,不過(guò),值傳遞是值的拷貝。引用傳遞是地址的拷貝,一般來(lái)說(shuō),地址拷貝更為高效。而值拷貝取決于拷貝的對(duì)象大小,對(duì)象越大,則性能越低。
3、map、slice、chan、指針、interface默認(rèn)以引用的方式傳遞。
4、函數(shù)的可變參數(shù)只能有一個(gè),且必須是最后一個(gè)。
5、在參數(shù)賦值時(shí)可以不用用一個(gè)一個(gè)的賦值,可以直接傳遞一個(gè)數(shù)組或者切片,特別注意的是在參數(shù)后加上“…”即可。
特殊函數(shù)
//匿名函數(shù)
var sum func(int, int) int = func(x, y int)int{return x+y}
sum := func(x, y int)int{return x+y}
//遞歸函數(shù)
func factorial(i int) int {
if i <= 1 {
return 1
}
return i * factorial(i-1)
}
延時(shí)調(diào)用 defer 注意
- 當(dāng)defer被聲明時(shí),參數(shù)被實(shí)時(shí)解析
- defer執(zhí)行順序?yàn)橄冗M(jìn)后出。
- defer 可以讀取有名返回值
感謝 Hugo&平臺(tái) OpenWrite 發(fā)布!