Golang学习笔记
Golang学习笔记
前言
2022年寒假,为了学习tinyKV课程而学习Golang,就写一些东西来记录一下吧
大括号不能换行是真的难受!
package
- package中的函数必须首字母大写才能被其他package调用
- package可以有init函数,该函数在package被import的时候会调用
变量、数组、切片
语法
var a int = 10
var p *int = &a
a := 10
p := &a
a := [4]int {1, 2, 3, 4}
b := [...]int {2, 3, 4)
a := []int {1, 2, 3, 4)
a := [3][2]string {
{"11", "12"},
{"21", "22"},
{"31", "32"}, //The comma is necessary
}
传递参数
Go中将数组作为参数进行传递的时候执行的是值传递,这与C++不同,需要特别注意。切片可以看成是对原数组的引用,改变切片也会改变原数组。
数组赋值
数组之间可以直接赋值,但数组的类型和长度要一样,如:
a := [5]int {1, 2, 3, 4, 5}
b := [5]int {6, 7, 8, 9, 10}
a = b
数组遍历
可以用for range遍历数组和切片
a := [5]int {1, 2, 3, 4, 5}
for i, v := range a {
//do something
}
for _, v := range a {
//do something
}
可以用len(a)获取a数组的长度
for i := 0; i < len(a); i++ {
fmt.Printf("%d th element is %d\n", i, a[i])
}
创建切片
用slc := a[st: ed]创建数组a在[st, ed)区间的切片
a := [5]int {1, 2, 3, 4, 5}
slc := a[1:4] //从a[1]到a[4-1]的切片
用make创建切片
func make([]T,len,cap)[]T 通过传递类型,长度和容量来创建切片。容量是可选参数, 默认值为切片长度。make 函数创建一个数组,并返回引用该数组的切片。
sld := make([]int, 5, 5)
fmt.Println(sld)
追加切片元素
sld := append(sld, 123, 34) //向sld中追加两个元素
函数
语法
func name(ele1 int, ele2 string) (rtnval1 int, rtnval2 string){
rtnval1 = 1
rtnval2 = "asd"
return
//
}
func main(){
val1, val2 := name(2, "zxc")
}
可变参数函数
只有最后一个参数可以为可变参数。当传入一组数时,会转化为切片,切片名为该可变参数名。可以使用语法糖直接将切片传递给可变参数
func f(nums ...int){
for _, v := range nums{
fmt.Printf("%d ", v)
}
}
func main()
{
f(1, 2, 3, 4)
a := []int {1, 2, 3, 4}
f(a...)//直接传递切片,在函数中改变nums将同时改变a
}
map
语法
mp := make(map[string]int)
mp := map[string]int {
"caution": 509,
"joker": 717,
"oyster": 213,
}
map[T1]T2是一个类型
var mp map[string]int
mp = make(map[string]int)//必须使用make初始化
添加、获取元素
同C++
删除元素
delete(mp, "joker")
map的长度
可用len(mp)获取
map是引用类型
当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。
mp1 := map[string]int {
"oyster": 1,
"caution": 2,
}
mp2 := mp1
mp2["oyster"] = 3
fmt.Println(mp1) //mp1也会改变
fmt.Println(mp2)
map作为参数进行传递的时候,也是如此。
rune
rune 是 Go 语言的内建类型,它也是 int32 的别称。在 Go 语言中,rune 表示一个代码点。代码点无论占用多少个字节,都可以用一个 rune 来表示。
func printString(s string){
r := []rune(s)
for i, v := range r {
fmt.Printf("%c", v)
}
}
结构体
语法
type E struct { //命名结构体
s1, s2 string
age int
}
func main(){
e1 := E {
s1 : "asd",
age : 3,
s2 : "zxc",
}
e2 := E{"asd", "zxc", 3}
}
func main(){
e3 := struct{ //匿名结构体
s1, s2 string
age int
}{
s1 : "asd",
age : 3,
s2 : "zxc",
}
}
指向结构体的指针
若p为指向结构体的指针,则可以用p.s1代替(*p).s1
匿名字段
省略变量名,用类型名代替变量名
type Person struct {
string
int
}
func main() {
var p1 Person
p1.string = "naveen"
p1.int = 50
fmt.Println(p1)
}
提升字段
若一个结构体中有匿名结构体,则可以像访问正常成员一样访问匿名结构体的成员
导出结构体、导出字段
首字母大写才能被其他包使用
方法
方法类似于类的成员函数
语法
func (e E) show(tms int) {
for i := 0; i < tms; i++ {
fmt.Println(e)
}
}
func main(){
e := E { "asd", "zxc", 3 }
e.show(3)
}
为了在一个类型上定义一个方法,方法的接收器类型定义和方法的定义应该在同一个包中。
指针接收器
使用指针接收器可以改变e的内容。当使用指针接收器时,e.show()和(&e).show()都是合法的