一、文件名、關(guān)鍵字與標(biāo)識符
文件名以.go結(jié)尾
-
標(biāo)識符與 C 家族中的其它語言相同。
36 個(gè)預(yù)定義標(biāo)識符
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 -
25個(gè)關(guān)鍵字
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 -
golang程序規(guī)范
- 命名使用駝峰命名法,且不能出現(xiàn)下劃線
- 根據(jù)首字母的大小寫來確定訪問權(quán)限追迟。無論是方法脆荷、常量、變量或結(jié)構(gòu)體的名稱集晚。
- 如果使用首字母大寫窗悯,則可以被其他包訪問
- 如果首字母小寫,則只能在本包中使用偷拔。
- 結(jié)構(gòu)體中屬性名的大寫蒋院,如果屬性名小寫,則會(huì)在數(shù)據(jù)解析時(shí)(如json解析或?qū)⒔Y(jié)構(gòu)體作為請求或訪問參數(shù))時(shí)無法解析莲绰。
二欺旧、基本結(jié)構(gòu)和要素
package main //歸屬于main包
import "fmt" // 導(dǎo)入 fmt 包(函數(shù)或其他元素)
//實(shí)現(xiàn)main包中的main函數(shù),該函數(shù)會(huì)自動(dòng)執(zhí)行
func main() {
fmt.Println("hello, world") // fmt 包中的 Println 函數(shù)蛤签,可以將字符串輸出到控制臺辞友,并在最后自動(dòng)增加換行字符 \n
}
1.包的概念、導(dǎo)入與可見性
1)文件的歸屬與包的導(dǎo)入
-
源文件中非注釋的第一行指明這個(gè)文件屬于哪個(gè)包顷啼,如:
package main
踏枣。-
package main
表示一個(gè)可獨(dú)立執(zhí)行的程序,不指定屬于main包的源程序钙蒙,則會(huì)被編譯為包(所有的包名都應(yīng)該使用小寫字母)茵瀑。 - 可以用一些較小的文件,并且在每個(gè)文件非注釋的第一行都使用
package main
來指明這些文件都屬于 main 包躬厌。
-
-
Go 程序是通過
import
關(guān)鍵字導(dǎo)入一組包马昨,包名被封閉在半角雙引號""
中。//import "包的路徑或 URL 地址" import "fmt" import "os" // 或 import ( "fmt" "os" ) // 被稱為因式分解關(guān)鍵字 //導(dǎo)入外部安裝包 //先安裝外部包到 $GOROOT/src/ 目錄 go install codesite.ext/author/goExample/goex import goex "codesite.ext/author/goExample/goex"
- 包在導(dǎo)入是可以使用相對路徑或絕對路徑
- 如果想要構(gòu)建一個(gè)程序扛施,則包和包內(nèi)的文件都必須以正確的順序進(jìn)行編譯鸿捧。包的依賴關(guān)系決定了其構(gòu)建順序。
-
Go 的標(biāo)準(zhǔn)庫包含了大量的包(如:fmt 和 os)疙渣,存放在
$GOROOT/pkg/$GOOS_$GOARCH/
目錄下匙奴。-
os
: 提供一個(gè)平臺無關(guān)性的操作系統(tǒng)功能接口,采用類Unix設(shè)計(jì)妄荔,隱藏了不同操作系統(tǒng)間差異泼菌,讓不同的文件系統(tǒng)和操作系統(tǒng)對象表現(xiàn)一致。 -
os/exec
: 提供運(yùn)行外部操作系統(tǒng)命令和程序的方式啦租。 -
syscall
: 底層的外部包哗伯,提供了操作系統(tǒng)底層調(diào)用的基本接口。
-
-
同一個(gè)包的源文件必須全部被一起編譯篷角。
- 對一個(gè)包進(jìn)行更改或重新編譯焊刹,所有引用了這個(gè)包的程序都必須全部重新編譯。
2)可見性規(guī)則
- 當(dāng)標(biāo)識符(包括常量、變量虐块、類型俩滥、函數(shù)名、結(jié)構(gòu)字段等等)以一個(gè)大寫字母開頭非凌,如:Group1举农,那么使用這種形式的標(biāo)識符的對象就可以被外部包的代碼所使用(客戶端程序需要先導(dǎo)入這個(gè)包),這被稱為導(dǎo)出(像面向?qū)ο笳Z言中的 public)敞嗡;
- 標(biāo)識符如果以小寫字母開頭,則對包外是不可見的航背,但是他們在整個(gè)包的內(nèi)部是可見并且可用的(像面向?qū)ο笳Z言中的 private )喉悴。
3)包的分級聲明和初始化
- 包內(nèi)可以定義或聲明 0 個(gè)或多個(gè)常量(const)、變量(var)和類型(type)玖媚,這些對象的作用域都是全局的(在本包范圍內(nèi))箕肃。
2.注釋
- 單行注釋以
//
開頭。 - 多行注釋均以
/*
開頭今魔,并以*/
結(jié)尾勺像。 - 每一個(gè)包應(yīng)該有相關(guān)注釋,在 package 語句之前的塊注釋將被默認(rèn)認(rèn)為是這個(gè)包的文檔說明
- 所有全局作用域的類型错森、常量吟宦、變量、函數(shù)和被導(dǎo)出的對象都應(yīng)該有一個(gè)合理的注釋涩维。
- godoc 工具會(huì)收集這些注釋并產(chǎn)生一個(gè)技術(shù)文檔殃姓。
3.打印
fmt包有printf與println兩個(gè)打印函數(shù)
-
Println :可以打印字符串和變量
a := 10 fmt.Println(a) fmt.Println("abc")
-
Printf : 可以打印出格式化的字符串,可以輸出字符串類型的變量瓦阐,不可以輸出其他類型變量
fmt.Printf("%v", str) //通用的占位符 %v 值的默認(rèn)格式蜗侈。 %+v 類似%v,但輸出結(jié)構(gòu)體時(shí)會(huì)添加字段名 %#v 相應(yīng)值的Go語法表示 %T 相應(yīng)值的類型的Go語法表示 %% 百分號,字面上的%,非占位符含義 //默認(rèn)格式%v下睡蟋,對于不同的數(shù)據(jù)類型踏幻,底層會(huì)去調(diào)用默認(rèn)的格式化方式: bool: %t int, int8 etc.: %d uint, uint8 etc.: %d, %x if printed with %#v float32, complex64, etc: %g string: %s chan: %p pointer: %p
4.變量、常量和類型
Go語言變量和常量的聲明方式與C和C++語言明顯不同戳杀, Go語言引入了關(guān)鍵字var该面,而類型信息放在變量或常量名之后。
1)變量
-
變量的聲明
var v1 int var v2 string var v3 [10]int // 數(shù)組 var v4 []int // 數(shù)組切片 var v5 struct { f int } var v6 *int // 指針 var v7 map[string]int // map豺瘤, key為string類型吆倦, value為int類型 var v8 func(a int) int
- Go 語言不使用分號作為語句的結(jié)束,實(shí)際上這一過程是由編譯器自動(dòng)完成坐求。
-
變量的聲明及初始化
// var關(guān)鍵字可以保留蚕泽,但不再是必要的元素 var v1 int = 10 // 正確的使用方式1 var v2 = 10 // 正確的使用方式2,編譯器可以自動(dòng)推導(dǎo)出v2的類型 v3 := 10 // 正確的使用方式3,編譯器可以自動(dòng)推導(dǎo)出v3的類型 // :=左側(cè)的變量不應(yīng)該是已經(jīng)被聲明過的须妻,否則會(huì)導(dǎo)致編譯錯(cuò)誤
-
變量的賦值
var v10 int v10 = 123
-
變量匿名
在調(diào)用函數(shù)時(shí)為了獲取一個(gè)值仔蝌,卻因?yàn)樵摵瘮?shù)返回多個(gè)值而不得不定義一堆沒用的變量。Go可以通過結(jié)合使用多重返回和匿名變量來避免這種丑陋的寫法
func GetName() (firstName, lastName, nickName string) { return "May", "Chan", "Chibi Maruko" } _, _, nickName := GetName()
2)常量
-
常量的聲明及初始化
const Pi float64 = 3.14159265358979323846 const zero = 0.0 // 無類型浮點(diǎn)常量 const ( size int64 = 1024 eof = -1 // 無類型整型常量 ) const u, v float32 = 0, 3 // u = 0.0, v = 3.0荒吏,常量的多重賦值 const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", 無類型整型和字符串常量
-
預(yù)定義常量: true敛惊、 false和iota。
//iota被認(rèn)為是一個(gè)可被編譯器修改的常量绰更,在每一個(gè)const關(guān)鍵字出現(xiàn)時(shí)被重置為0瞧挤,然后在下一個(gè)const出現(xiàn)之前,每出現(xiàn)一次iota儡湾,其所代表的數(shù)字會(huì)自動(dòng)增1特恬。 const ( // iota被重設(shè)為0 c0 = iota // c0 == 0 c1 = iota // c1 == 1 c2 = iota // c2 == 2 ) const ( u = iota * 42 // u == 0 v float64 = iota * 42 // v == 42.0 w = iota * 42 // w == 84 ) //如果兩個(gè)const的賦值語句的表達(dá)式是一樣的,那么可以省略后一個(gè)賦值表達(dá)式徐钠。 const ( // iota被重設(shè)為0 c0 = iota // c0 == 0 c1 // c1 == 1 c2 // c2 == 2 )
3)類型
-
基礎(chǔ)類型
- 布爾類型: bool
- 整型: int8癌刽、 byte、 int16尝丐、 int显拜、 uint、 uintptr等
- 浮點(diǎn)類型: float32爹袁、 float64远荠。
- 復(fù)數(shù)類型: complex64、 complex128呢簸。
- 字符串: string矮台。
- 字符類型: rune。
- 錯(cuò)誤類型: error根时。
-
復(fù)合類型
指針(pointer)
-
數(shù)組(array)
//數(shù)組(array) var a [3]int
var b [3]int = [3]int{1, 2, 3}
c := [...]int{1, 2}
fmt.Println(a[0])
//二維數(shù)組
d := [3][5]int
d[0][1] = 0- 切片(slice) - Slice(切片)代表變長的序列瘦赫,序列中每個(gè)元素都有相同的類型。一個(gè)slice類型一般寫作[]T蛤迎,其中T代表slice中元素的類型确虱;slice的語法和數(shù)組很像,只是沒有固定長度而已替裆。 ```go //聲明切片的格式 var identifier []type //不需要說明長度 d := [...]int{1, 2,3,4,5,6,7,8,9} var slice1 []int = d[2:5] //用 make() 創(chuàng)建一個(gè)切片 slice1 := make([]int, 50, 100) //用 new() 創(chuàng)建一個(gè)切片 slice2 := new([100]int)[0:50] ``` - 字典(map) - map類型可以寫為map[K]V校辩,其中K和V分別對應(yīng)key和value。 ```go ages := map[string]int{ "alice": 31, "charlie": 34, } ages["alice"] = 32 fmt.Println(ages["alice"]) // "32" ``` - 通道(chan) - 結(jié)構(gòu)體(struct) ```go type Employee struct { ID int //編譯器在行末自動(dòng)添加逗號 Name string Address string DoB time.Time Position string Salary int ManagerID int } var dilbert Employee
-
接口(interface)
interface是一組方法簽名的組合
-
空interface(interface{})不包含任何的方法辆童,空接口類型對滿足它的類型沒有要求宜咒,所以我們可以為空接口分配任何值。
var any interface{} any = true any = 12.34 any = "hello" any = map[string]int{"one": 1} any = new(bytes.Buffer) // interface轉(zhuǎn)換成具體類型調(diào)用方式:interfaceVar.(具體類型) // 原理:斷言 any.(int) any.(string) any.(byte) any.(float32)
-
JSON
-
JavaScript對象表示法(JSON)是一種用于發(fā)送和接收結(jié)構(gòu)化信息的標(biāo)準(zhǔn)協(xié)議把鉴。JSON是對JavaScript中各種類型的值(字符串故黑、數(shù)字儿咱、布爾值)和對象(Unicode本文)的編碼。
//1.編組(marshaling):結(jié)構(gòu)體slice轉(zhuǎn)為JSON格式數(shù)據(jù) type Movie struct { Title string Year int `json:"released"` Color bool `json:"color,omitempty"` Actors []string } var movies = []Movie{ {Title: "Casablanca", Year: 1942, Color: false, Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}}, {Title: "Cool Hand Luke", Year: 1967, Color: true, Actors: []string{"Paul Newman"}}, {Title: "Bullitt", Year: 1968, Color: true, Actors: []string{"Steve McQueen", "Jacqueline Bisset"}}, // ... } data, err := json.Marshal(movies) if err != nil { log.Fatalf("JSON marshaling failed: %s", err) } fmt.Printf("%s\n", data) //打印結(jié)果 [{"Title":"Casablanca","released":1942,"Actors":["Humphrey Bogart","Ingr id Bergman"]},{"Title":"Cool Hand Luke","released":1967,"color":true,"Ac tors":["Paul Newman"]},{"Title":"Bullitt","released":1968,"color":true," Actors":["Steve McQueen","Jacqueline Bisset"]}] //2.將JSON格式數(shù)據(jù)解碼為一個(gè)結(jié)構(gòu)體slice var titles []struct{ Title string } if err := json.Unmarshal(data, &titles); err != nil { log.Fatalf("JSON unmarshaling failed: %s", err) } fmt.Println(titles) // "[{Casablanca} {Cool Hand Luke} {Bullitt}]"
-
4)自定義類型
使用關(guān)鍵字type自定義類型
//自定義類型
type IZ int
var a IZ = 5
//定義多類型场晶,使用因式分解關(guān)鍵字的方式
type (
IZ int
FZ float64
STR string
)
5)類型轉(zhuǎn)換
//int與float轉(zhuǎn)換
var a float32 = 1234.12345678
b := int64(a)
c := float32(a)
d := float64(a)
e := float64(c)
// []byte轉(zhuǎn)int(16進(jìn)制轉(zhuǎn)10進(jìn)制)
import "fmt"
import "encoding/binary"
var a []byte = []byte{0, 1, 2, 3}
binary.BigEndian.Uint32(a) //0x00010203 ==> 66051
binary.LittleEndian.Uint32(a) //0x03020100 ==> 50462976
b : = []byte{0x00, 0x00, 0x03, 0xe8}
b_buf : = bytes .NewBuffer(b)
var x int32
binary.Read(b_buf, binary.BigEndian, &x)
fmt.Println(x)
b := []byte{0xe8, 0x03, 0xd0, 0x07}
x1 := binary.LittleEndian.Uint32(b[0:])
// int 轉(zhuǎn) []byte
x = 1000
b_buf := bytes .NewBuffer([]byte{})
binary.Write(b_buf, binary.BigEndian, x)
fmt.Println(b_buf.Bytes())
// float32 轉(zhuǎn)uint32
math.Float32bits(f float32) uint32
// uint32 轉(zhuǎn) float32
Float32frombits(b uint32) float32
//uint32 轉(zhuǎn) []byte
func EncodeUint32(v uint32) []uint8 {
b := make([]uint8, 4)
binary.LittleEndian.PutUint32(b, v)
return b
}
// string 轉(zhuǎn) []byte
var str string = "test"
var data []byte = []byte(str)
// []byte 轉(zhuǎn) string
var data [10]byte
var str string = string(data[:])
// []byte -> String (byte轉(zhuǎn)ascii)
data1 := []byte{0x31, 0x32, 0x33, 0x34}
data2 := []byte("Hello")
str1 := string(data1) //"1234"
str2 := string(data2) //"Hello"
// []byte -> String (byte轉(zhuǎn)hex)
import "encoding/hex"
hexstr := hex.EncodeToString(data1) //"31323334"
// String -> []byte (hex轉(zhuǎn)byte)
tmp, _ := hex.DecodeString(hexstr) //[49 50 51 52]
//===strconv包實(shí)現(xiàn)基本數(shù)據(jù)類型的字符串表示形式之間的轉(zhuǎn)換===
import "strconv"
//數(shù)值轉(zhuǎn)換
//int轉(zhuǎn)string
strconv.Itoa(i int) string
//string轉(zhuǎn)int
strconv.Atoi(s string) (i int, err error)
//將字符串轉(zhuǎn)換為值
//string轉(zhuǎn)bool
b, err := strconv.ParseBool("true")
//string轉(zhuǎn)float64
f, err := strconv.ParseFloat("3.1415", 64)
//string轉(zhuǎn)int64混埠,10進(jìn)制表示
i, err := strconv.ParseInt("-42", 10, 64)
//string轉(zhuǎn)uint64
u, err := strconv.ParseUint("42", 10, 64)
//將值轉(zhuǎn)換為字符串
//bool轉(zhuǎn)string
s := strconv.FormatBool(true)
//float64轉(zhuǎn)string 64
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
//int64轉(zhuǎn)string,以10進(jìn)制顯示
s := strconv.FormatInt(-42, 10)
//uint64轉(zhuǎn)string诗轻,以10進(jìn)制顯示
s := strconv.FormatUint(42, 10)
5.運(yùn)算符
數(shù)值運(yùn)算
-
比較運(yùn)算
==
钳宪、
!=、
<扳炬、
<=吏颖、
>、
>= -
位運(yùn)算
按位與
&
鞠柄、按位或|
侦高、按位異或^
、 -
字符串操作
//字符串拼接 s := "hel" + "lo," s += "world!" strings.Join(sl []string, sep string) string //字符串分割 //將會(huì)利用 1 個(gè)或多個(gè)空白符號來作為動(dòng)態(tài)長度的分隔符將字符串分割成若干小塊 sl := strings.Fields(str) for _, val := range sl { fmt.Printf("%s - ", val) } //自定義分割符號來對指定字符串進(jìn)行分割 sl2 := strings.Split(str2, "|") for _, val := range sl2 { fmt.Printf("%s - ", val) } // 注意:val[1:len(val)-1]才是真正的目標(biāo)字符串 //判斷前綴 strings.HasPrefix(str, "Th") bool //判斷后綴 strings.HasSuffix(str, "er") bool //字符串包含關(guān)系 strings.Contains(str, substr) bool //判斷子字符串或字符在父字符串中首次出現(xiàn)的位置 strings.Index(s, str string) int //判斷子字符串或字符在父字符串中最后出現(xiàn)的位置 strings.LastIndex(s, str string) int //字符串替換 //將字符串 str 中的前 n 個(gè)字符串 old 替換為字符串 new, n = -1 則替換所有字符 strings.Replace(str, old, new, n) string //統(tǒng)計(jì)字符串出現(xiàn)次數(shù) strings.Count(s, str) int //修改字符串大小寫 strings.ToLower(s) string strings.ToUpper(s) string
6.Go 程序的一般結(jié)構(gòu)示例
package main //被 main 包引用厌杜,是一個(gè)可獨(dú)立執(zhí)行的程序
import (
"fmt"
)
const c = "C"
var v int = 5
type T struct{}
//每個(gè)源文件都只能包含一個(gè) init 函數(shù), 執(zhí)行優(yōu)先級比 main 函數(shù)高
func init() { // initialization of package
}
func main() {
var a int
Func1()
// ...
fmt.Println(a)
}
func (t T) Method1() {
//...
}
func Func1() { // exported function Func1
//...
}
Go 程序的執(zhí)行順序:
- 按順序?qū)胨斜?main 包引用的其它包登馒,然后在每個(gè)包中執(zhí)行如下流程:
- 如果該包又導(dǎo)入了其它的包,則從第一步開始遞歸執(zhí)行,但是每個(gè)包只會(huì)被導(dǎo)入一次。
- 然后以相反的順序在每個(gè)包中初始化常量和變量,如果該包含有 init 函數(shù)的話寨躁,則調(diào)用該函數(shù)话肖。
- 在完成這一切之后,main 也執(zhí)行同樣的過程,最后調(diào)用 main 函數(shù)開始執(zhí)行程序。
三蒂培、控制結(jié)構(gòu)
1.if-else
if condition1 {
// do something
} else if condition2 {
// do something else
} else {
// catch-all or default
}
//示例
func main() {
var first int = 10
var cond int
if first <= 0 {
fmt.Printf("first is less than or equal to 0\n")
} else if first > 0 && first < 5 {
fmt.Printf("first is between 0 and 5\n")
} else {
fmt.Printf("first is 5 or greater\n")
}
if cond = 5; cond > 10 {
fmt.Printf("cond is greater than 10\n")
} else {
fmt.Printf("cond is not greater than 10\n")
}
}
2.switch
// 方式1
switch var1 {
case val1:
...
case val2:
...
default:
...
}
//示例
func main() {
var num1 int = 100
switch num1 {
case 98, 99:
fmt.Println("It's equal to 98")
case 100:
fmt.Println("It's equal to 100")
default:
fmt.Println("It's not equal to 98 or 100")
}
}
//方式2
switch {
case condition1:
...
case condition2:
...
default:
...
}
//示例
func main() {
var num1 int = 7
switch {
case num1 < 0:
fmt.Println("Number is negative")
case num1 > 0 && num1 < 10:
fmt.Println("Number is between 0 and 10")
default:
fmt.Println("Number is 10 or greater")
}
}
3.for
// 格式
for 初始化語句; 條件語句; 修飾語句 {
// do something
}
//示例
func main() {
for i := 0; i < 5; i++ {
fmt.Printf("This is the %d iteration\n", i)
}
}
//for-range 結(jié)構(gòu)
for i, char := range str {
...
}
//示例
func main() {
str := "Go is a beautiful language!"
fmt.Printf("The length of str is: %d\n", len(str))
for pos, char := range str {
fmt.Printf("Character on position %d is: %c \n", pos, char)
}
}
四钳枕、函數(shù)
Go 里面有三種類型的函數(shù):
- 普通的帶有名字的函數(shù)
- 匿名函數(shù)或者lambda函數(shù)
- 方法(Methods)
1.普通函數(shù)
//普通函數(shù)格式
// 入口參數(shù):parameter_list 的形式為 (param1 type1, param2 type2, …)
// 回調(diào)參數(shù): return_value_list 的形式為 (ret1 type1, ret2 type2, …)
func functionName(parameter_list) (return_value_list) {
…
}
//示例
func Atoi(s string) (i int, err error)
//調(diào)用
num, err := Atoi("12")
//自定義一個(gè)函數(shù)類型別名
type name func(type1,type2) type3
//示例
type binOp func(int, int) int
add := binOp
- 左大括號
{
必須與方法的聲明放在同一行,這是編譯器的強(qiáng)制規(guī)定硬爆,大括號{}
的使用規(guī)則在任何時(shí)候都相同。 - 函數(shù)也是一個(gè)類型糟把,可以作為參數(shù)
2.匿名函數(shù)
func(parameter_list) (return_value_list) {...}
//示例
fplus := func(x, y int) int { return x + y }
num := fpus(1,2)
- 匿名函數(shù)不能夠獨(dú)立存在绢涡,但可以被賦值于某個(gè)變量
3.方法
面向?qū)ο缶幊蹋∣OP)把對象作為程序的基本單元,一個(gè)對象包含了數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)遣疯。把程序視為一組對象的集合雄可,而每個(gè)對象都可以接收其他對象發(fā)過來的消息,并處理這些消息缠犀,程序的執(zhí)行就是一系列消息在各個(gè)對象之間傳遞数苫。
五、數(shù)組與切片
聲明數(shù)組的格式是: var identifier [n]type
把一個(gè)大數(shù)組傳遞給函數(shù)會(huì)消耗很多內(nèi)存辨液。有兩種方法可以避免這種現(xiàn)象:
- 傳遞數(shù)組的指針
- 使用數(shù)組的切片
切片(slice)是對數(shù)組一個(gè)連續(xù)片段的引用虐急,這個(gè)片段可以是整個(gè)數(shù)組,或者是由起始和終止索引標(biāo)識的一些項(xiàng)的子集滔迈。多個(gè)切片如果表示同一個(gè)數(shù)組的片段止吁,它們可以共享數(shù)據(jù);因此一個(gè)切片和相關(guān)數(shù)組的其他切片是共享存儲(chǔ)的燎悍。
聲明切片的格式:
var identifier []type
赏殃,一個(gè)切片在未初始化之前默認(rèn)為 nil,長度為 0间涵。-
切片的初始化格式:
var slice1 []type = arr1[start:end]
-
arr1[2:]
和arr1[2:len(arr1)]
相同,都包含了數(shù)組從第三個(gè)到最后的所有元素榜揖。arr1[:3]
和arr1[0:3]
相同勾哩,包含了從第一個(gè)到第三個(gè)元素(不包括第三個(gè))。
-
1.new() 和 make() 的區(qū)別
-
func new(Type) *[Type]:內(nèi)置函數(shù) new 會(huì)分配內(nèi)存举哟。第一個(gè)參數(shù)是一個(gè)類型思劳,而不是值,并且返回值是一個(gè)指向該類型零值的指針妨猩。
var p *[]int = new([]int) // *p == nil; with len and cap 0
-
func make(t Type, size ...IntegerType) Type :內(nèi)置函數(shù) make 分配并初始化 slice潜叛,map 或者 chan。和 new 類似壶硅,第一個(gè)參數(shù)為參數(shù)的類型威兜,而不是一個(gè)值。和 new 不同的是 make 返回的類型和參數(shù)類型相同庐椒,而不是一個(gè)指向該類型的指針椒舵。
//分配一個(gè)有 50 個(gè) int 值的數(shù)組,并且創(chuàng)建了一個(gè)長度為 10约谈,容量為 50 的 切片 v笔宿,該 切片 指向數(shù)組的前 10 個(gè)元素犁钟。 var v []int = make([]int, 10, 50) //slice1 := make([]type,init_length, capacity)
2.For-range 結(jié)構(gòu)
//這種構(gòu)建方法可以應(yīng)用于字符串(本質(zhì)是字節(jié)數(shù)組)、數(shù)組和切片
for ix, value := range slice1 {
...
}
3.切片的復(fù)制與追加
如果想增加切片的容量泼橘,我們必須創(chuàng)建一個(gè)新的更大的切片并把原分片的內(nèi)容都拷貝過來涝动。
//復(fù)制切片
sl_from := []int{1, 2, 3}
sl_to := make([]int, 10)
n := copy(sl_to, sl_from)
//追加切片
sl3 := []int{1, 2, 3}
sl3 = append(sl3, 4, 5, 6)
append 方法將 0 個(gè)或多個(gè)具有相同類型 s 的元素追加到切片后面并且返回新的切片
如果 s 的容量不足以存儲(chǔ)新增元素,append 會(huì)分配新的切片來保證已有切片元素和新增元素的存儲(chǔ)炬灭。
六醋粟、Map
map 是一種特殊的數(shù)據(jù)結(jié)構(gòu):一種元素對(pair)的無序集合,pair 的一個(gè)元素是 key担败,對應(yīng)的另一個(gè)元素是 value昔穴,所以這個(gè)結(jié)構(gòu)也稱為關(guān)聯(lián)數(shù)組或字典。
1.概念
1)map的聲明及初始化
var map1 map[keytype]valuetype
var mapLit map[string]int
mapLit = map[string]int{"one": 1, "two": 2}
//通過make函數(shù)初始化
var map1 = make(map[keytype]valuetype)
在聲明的時(shí)候不需要知道 map 的長度提前,map 是可以動(dòng)態(tài)增長的吗货。
key 可以是任意可以用 == 或者 != 操作符比較的類型,比如 string狈网、int宙搬、float。
value 可以是任意類型
五拓哺、包(Package)
1.標(biāo)準(zhǔn)庫
像 fmt
勇垛、os
等這樣具有常用功能的內(nèi)置包在 Go 語言中有 150 個(gè)以上。
unsafe
: 包含了一些打破 Go 語言“類型安全”的命令士鸥,一般的程序中不會(huì)被使用闲孤,可用在 C/C++ 程序的調(diào)用中。
syscall
-os
-os/exec
:
-
os
: 提供一個(gè)平臺無關(guān)性的操作系統(tǒng)功能接口烤礁,采用類Unix設(shè)計(jì)讼积,隱藏了不同操作系統(tǒng)間差異,讓不同的文件系統(tǒng)和操作系統(tǒng)對象表現(xiàn)一致脚仔。 -
os/exec
: 提供運(yùn)行外部操作系統(tǒng)命令和程序的方式勤众。 -
syscall
: 底層的外部包,提供了操作系統(tǒng)底層調(diào)用的基本接口鲤脏。