Golang 基础学习笔记
Golang 基础学习笔记
Go 语言特色
- 简洁、快速、安全
- 并行、有趣、开源
- 内存管理、数组安全、编译迅速
Go 语言用途
Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。
对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。
它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。
Go 语言结构
Go 语言的基础组成有以下几个部分:
- 包声明
- 引入包
- 函数
- 变量
- 语句 & 表达式
- 注释
package main
import "fmt"
func main() {
/* 这是我的第一个简单的程序 */
fmt.Println("Hello, World!")
}
Go 语言基础语法
Go 标记
Go 程序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号。如以下 GO 语句由 6 个标记组成:
1. fmt
2. .
3. Println
4. (
5. "Hello, World!"
6. )
行分隔符
在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。
如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。
注释
注释不会被编译,每一个包应该有相关注释。
单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。如:
// 单行注释
/*
Author by MuYusen
我是多行注释
*/
标识符
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
关键字
25 个关键字或保留字:
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
36 个预定义标识符
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
程序一般由关键字、常量、变量、运算符、类型和函数组成。
程序中可能会使用到这些分隔符:括号 (),中括号 [] 和大括号 {}。
程序中可能会使用到这些标点符号:.、,、;、: 和 …。
Go 语言的空格
Go 语言中变量的声明必须使用空格隔开,如:
var age int;
语句中适当使用空格能让程序更易阅读。
无空格:
fruit=apples+oranges;
在变量与运算符间加入空格,程序看起来更加美观,如:
fruit = apples + oranges;
Go 语言数据类型
序号|类型和描述 -|- 1|布尔型<br />布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。 2|数字类型<br />整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码。 3|字符串类型:<br />字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。 4|派生类型:<br />包括:<br />(a) 指针类型(Pointer)<br />(b) 数组类型<br />(c) 结构化类型(struct)<br />(d) Channel 类型<br />(e) 函数类型<br />(f) 切片类型<br />(g) 接口类型interface)<br />(h) Map 类型
数字类型
基于架构的类型,例如:int、uint 和 uintptr。
序号|类型和描述 -|- 1|uint8<br />无符号 8 位整型 (0 到 255) 2|uint16<br />无符号 16 位整型 (0 到 65535) 3|uint32<br />无符号 32 位整型 (0 到 4294967295) 4|uint64<br />无符号 64 位整型 (0 到 18446744073709551615) 5|int8<br />有符号 8 位整型 (-128 到 127) 6|int16<br />有符号 16 位整型 (-32768 到 32767) 7|int32<br />有符号 32 位整型 (-2147483648 到 2147483647) 8|int64<br />有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
浮点型:
序号|类型和描述 -|- 1|float32<br />IEEE-754 32位浮点型数 2|float64<br />IEEE-754 64位浮点型数 3|complex64<br />32 位实数和虚数 4|complex128<br />64 位实数和虚数
其他数字类型
序号|类型和描述 -|- 1|byte<br />类似 uint8 2|rune<br />类似 int32 3|uint<br />32 或 64 位 4|int<br />与 uint 一样大小 5|uintptr<br />无符号整型,用于存放一个指针
Go 语言变量
Go 语言变量名由字母、数字、下划线组成,其中首个字母不能为数字。
声明变量的一般形式是使用 var 关键字:
var indentifer type
变量声明
- 第一种,指定变量类型,声明后若不赋值,使用默认值。
var v_name v_type
v_name = value
- 第二种,根据值自行判定变量类型。
var v_name = value
- 第三种,省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误。
v_name := value
// 例如
var a int = 10
var b = 10
c := 10
多变量声明
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
值类型和引用类型
所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:
当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝:
Go 语言常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式:
const identifier [type] = value
可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。
- 显式类型定义: const b string = "abc"
- 隐式类型定义: const b = "abc"
多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2
常量还可以用作枚举:
const (
Unknown = 0
Female = 1
Male = 2
)
常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过;
iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "gaga" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
Go 语言数组
Go 语言提供了数组类型的数据结构。
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。
数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为 0,第二个索引为 1,以此类推。
声明数组
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var variable_name [SIZE] variable_type
以上为一维数组的定义方式。数组长度必须是整数且大于 0。例如以下定义了数组 balance 长度为 10 类型为 float32:
var balance [10] float32
初始化数组
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
初始化数组中 {} 中的元素个数不能大于 [] 中的数字。
如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
该实例与上面的实例是一样的,虽然没有设置数组的大小。
balance[4] = 50.0
以上实例读取了第五个元素。数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为 0,第二个索引为 1,以此类推。
访问数组元素
数组元素可以通过索引(位置)来读取。格式为数组名后加中括号,中括号中为索引的值。
更多内容
数组对 Go 语言来说是非常重要的,以下我们将介绍数组更多的内容:
内容 | 描述 |
---|---|
多维数组 | Go 语言支持多维数组,最简单的多维数组是二维数组 |
向函数传递数组 | 你可以向函数传递数组参数 |
Go 语言多维数组
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
向函数传递数组
package main
import "fmt"
func main() {
/* 数组长度为 5 */
var balance = []int {1000, 2, 3, 17, 50}
var avg float32
/* 数组作为参数传递给函数 */
avg = getAverage( balance, 5 ) ;
/* 输出返回的平均值 */
fmt.Printf( "平均值为: %f ", avg );
}
func getAverage(arr []int, size int) float32 {
var i,sum int
var avg float32
for i = 0; i < size;i++ {
sum += arr[i]
}
avg = float32(sum) / float32(size)
return avg;
}
Go 语言指针
变量是一种使用方便的占位符,用于引用计算机内存地址。
Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。
什么是指针
一个指针变量指向了一个值的内存地址。
类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name *var-type
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明:
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
如何使用指针
指针使用流程:
- 定义指针变量。
- 为指针变量赋值。
- 访问指针变量中指向地址的值。
在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。
func test_pointer() {
fmt.Println("#### 指针 ####")
var ptr *int
var zfs int = 100
fmt.Println(zfs)
fmt.Println(reflect.TypeOf(zfs))
fmt.Println(ptr)
fmt.Println(reflect.TypeOf(ptr))
//fmt.Println(*ptr)
ptr = &zfs
fmt.Println(ptr)
fmt.Println(reflect.TypeOf(ptr))
fmt.Println(*ptr)
}
Go 空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
一个指针变量通常缩写为 ptr。
空指针判断:
if(ptr != nil) /* ptr 不是空指针 */
if(ptr == nil) /* ptr 是空指针 */
Go指针更多内容
内容 | 描述 |
---|---|
Go 指针数组 | 你可以定义一个指针数组来存储地址 |
Go 指向指针的指针 | Go 支持指向指针的指针 |
Go 向函数传递指针参数 | 通过引用或地址传参,在函数调用时可以改变其值 |
Go 语言结构体
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:
- Title :标题
- Author : 作者
- Subject:学科
- ID:书籍ID
定义结构体
结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体有中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type struct {
member definition;
member definition;
...
member definition;
}
一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:
variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
访问结构体成员
如果要访问结构体成员,需要使用点号 . 操作符,格式为:
结构体.成员名"
结构体类型变量使用 struct 关键字定义.
结构体作为函数参数
可以像其他数据类型一样将结构体类型作为参数传递给函数。并以以上实例的方式访问结构体变量:
结构体指针
可以定义指向结构体的指针类似于其他指针变量,格式如下:
var struct_pointer *Books
以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,可以将 & 符号放置于结构体变量前:
struct_pointer = &Book1;
使用结构体指针访问结构体成员,使用 "." 操作符:
struct_pointer.title;
func printBook( book *Books ) {
fmt.Printf( "Book title : %s\n", book.title);
fmt.Printf( "Book author : %s\n", book.author);
fmt.Printf( "Book subject : %s\n", book.subject);
fmt.Printf( "Book book_id : %d\n", book.book_id);
}
Go 语言运算符
运算符用于在程序运行时执行数学或逻辑运算。
Go 语言内置的运算符有:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 其他运算符
算术运算符
假定 A 值为 100,B 值为 200。
运算符 | 描述 | 实例 |
---|---|---|
+ | 相加 | A + B 输出结果 300 |
- | 相减 | A - B 输出结果 -100 |
* | 相乘 | A * B 输出结果 20000 |
/ | 相除 | B / A 输出结果 2 |
% | 求余 | B % A 输出结果 0 |
++ | 自增 | A++ 输出结果 101 |
-- | 自减 | A-- 输出结果 99 |
关系运算符
假定 A 值为 1,B 值为 2。
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 | (A == B) 为 False |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 | (A != B) 为 True |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 | (A > B) 为 False |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 | (A < B) 为 True |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 | (A >= B) 为 False |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 | (A <= B) 为 True |
逻辑运算符
假定 A 值为 True,B 值为 False。
运算符 | 描述 | 实例 |
---|---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 | (A && B) 为 False |
` | ` | |
! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 | !(A && B) 为 True |
位运算符
位运算符对整数在内存中的二进制位进行操作。
下表列出了位运算符 &, |, 和 ^ 的计算:
p| q| p & q| p |
q| p ^ q -|---|-------|---------|- 0|0|0|0|0 0|1|0|1|1 1|1|1|1|0 1|0|0|1|1
赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 | C = A + B 将 A + B 表达式结果赋值给 C |
+= | 相加后再赋值 | C += A 等于 C = C + A |
-= | 相减后再赋值 | C -= A 等于 C = C - A |
*= | 相乘后再赋值 | C *= A 等于 C = C * A |
/= | 相除后再赋值 | C /= A 等于 C = C / A |
%= | 求余后再赋值 | C %= A 等于 C = C % A |
<<= | 左移后赋值 | C <<= 2 等于 C = C << 2 |
>>= | 右移后赋值 | C >>= 2 等于 C = C >> 2 |
&= | 按位与后赋值 | C &= 2 等于 C = C & 2 |
^= | 按位异或后赋值 | C ^= 2 等于 C = C ^ 2 |
` | =` | 按位或后赋值 |
其他运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 返回变量存储地址 | &a; 将给出变量的实际地址。 |
* | 指针变量。 | *a; 是一个指针变量 |
运算符优先级
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低
优先级 | 运算符 |
---|---|
7 | ^ ! |
6 | * / % << >> & &^ |
5 | `+ - |
4 | == != < <= >= > |
3 | <- |
2 | && |
1 | ` |
Go 语言条件语句
条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句。
Go 语言提供了以下几种条件判断语句:
语句 | 描述 |
---|---|
if 语句 | if 语句 由一个布尔表达式后紧跟一个或多个语句组成。 |
if...else 语句 | if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。 |
if 嵌套语句 | 你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。 |
switch 语句 | switch 语句用于基于不同条件执行不同动作。 |
select 语句 | select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。 |
Go 语言循环语句
Go 语言提供了以下几种类型循环处理语句:
循环类型 | 描述 |
---|---|
for 循环 | 重复执行语句块 |
循环嵌套 | 在 for 循环中嵌套一个或多个 for 循环 |
循环控制语句
循环控制语句可以控制循环体内语句的执行过程。
GO 语言支持以下几种循环控制语句:
控制语句 | 描述 |
---|---|
break 语句 | 经常用于中断当前 for 循环或跳出 switch 语句 |
continue 语句 | 跳过当前循环的剩余语句,然后继续进行下一轮循环。 |
goto 语句 | 将控制转移到被标记的语句。 |
无限循环
如过循环中条件语句永远不为 false 则会进行无限循环.
Go 语言 for 循环
Go语言的For循环有3中形式,只有其中的一种使用分号。
- 和 C 语言的 for 一样:
for init; condition; post { }
- 和 C 的 while 一样:
for condition { }
- 和 C 的 for(;;) 一样:
for { }
- for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap {
newMap[key] = value
}
Go 语言函数
函数是基本的代码块,用于执行一个任务。
Go 语言最少有个 main() 函数。
函数声明告诉了编译器函数的名称、返回类型和参数。
Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的元素个数。
函数定义
Go 语言函数定义格式如下:
func function_name( [parameter list] ) [return_types] {
函数体
}
函数定义解析:
- func:函数由 func 开始声明
- function_name:函数名称,函数名和参数列表一起构成了函数签名。
- parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
- return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
- 函数体:函数定义的代码集合。
函数调用
当创建函数时,你定义了函数需要做什么,通过调用该函数来执行指定任务。
调用函数,向函数传递参数,并返回值.
函数返回多个值
Go 函数可以返回多个值,例如:
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("z", "m")
fmt.Println(a, b)
}
函数参数
函数如果使用参数,该变量可称为函数的形参。
形参就像定义在函数体内的局部变量。
调用函数,可以通过两种方式来传递参数:
传递类型 | 描述 |
---|---|
值传递 | 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 |
引用传递 | 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 |
默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。
函数用法
函数用法 | 描述 |
---|---|
函数作为值 | 函数定义后可作为值来使用 |
闭包 | 闭包是匿名函数,可在动态编程中使用 |
方法 | 方法就是一个包含了接受者的函数 |
Go 语言函数作为值
Go 语言可以很灵活的创建函数,并作为值使用。以下实例中我们在定义的函数中初始化一个变量.
package main
import (
"fmt"
"math"
)
func main(){
/* 声明函数变量 */
getsum := func(a, b int) int {
return a + b
}
/* 使用函数 */
fmt.Println(getsum(5, 10))
}
Go 语言函数闭包
Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。
以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:
package main
import "fmt"
func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
}
func main(){
/* nextNumber 为一个函数,函数 i 为 0 */
nextNumber := getSequence()
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())
/* 创建新的函数 nextNumber1,并查看结果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}
Go 语言函数方法
面向对象了
Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。语法格式如下:
func (variable_name variable_data_type) function_name() [return_type]{
/* 函数体*/
}
下面定义一个结构体类型和该类型的一个方法:
package main
import (
"fmt"
)
/* 定义结构体 */
type Circle struct {
radius float64
}
func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("Area of Circle(c1) = ", c1.getArea())
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
//c.radius 即为 Circle 类型对象中的属性
return 3.14 * c.radius * c.radius
}
Go 语言变量作用域
作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
Go 语言中变量可以在三个地方声明:
- 函数内定义的变量称为局部变量
- 函数外定义的变量称为全局变量
- 函数定义中的变量称为形式参数
局部变量
在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
全局变量
在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。
全局变量可以在任何函数中使用。
Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑。
形式参数
形式参数会作为函数的局部变量来使用。
初始化局部和全局变量
不同类型的局部和全局变量默认值为:
数据类型 | 初始化默认值 |
---|---|
int | 0 |
float32 | 0 |
pointer | nil |
Go 语言切片(Slice)
Go 语言切片是对数组的抽象。本质还是数组。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
定义切片
- 可以声明一个未指定大小的数组来定义切片:
var identifier []type
切片不需要说明长度。
- 使用make()函数来创建切片:
var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)
- 也可以指定容量,其中capacity为可选参数。
make([]T, length, capacity)
这里 len 是数组的长度并且也是切片的初始长度。
Go 语言Map(集合)
Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
定义 Map
可以使用内建函数 make 也可以使用 map 关键字来定义 Map:
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)
var countryCapitalMap map[string]string /*创建集合 */
countryCapitalMap = make(map[string]string)
delete() 函数
delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。
Go 语言范围(Range)
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。
Go 语言接口
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] {
/* 方法实现*/
}
Go 错误处理
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
error类型是一个接口类型,这是它的定义:
type error interface {
Error() string
}
0条评论