Go语言基础 Part1

说明

本文为GO语言基础的学习笔记

基本语法

  1. go语言中没有 引用
  2. 不定参函数

    1
    2
    3
    4
    5
    6
    func test(args ...int){
    for i:=0;i<len(args);i++{
    fmt.Println("下标 ",i,"值 ",args[i])
    }

    }
  3. 多返回值

    1
    2
    3
    4
    5
    func test5()(a int, b int, c int){
    //多重赋值
    a,b,c=1,2,3
    return
    }
  4. 匿名变量_
    匿名变量与函数无效返回值搭配使用

  1. 函数类型
    函数也可以作为变量使用,通过传入参参数和返回参数标记不同函数类型。
    函数名是一个指针

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    package main

    import "fmt"

    func test6(){
    fmt.Println("arigado")
    }
    func test7(a int, b int){
    fmt.Println(a+b)
    }
    func test9(a int, b int) int{
    return a+b
    }
    func test8() {
    fmt.Println("sumanai")
    }
    //type 可以定义函数类型
    //type 可以为已存在类型起别名
    type FUNCTYPE func()
    type FUNCTEST func(int,int)
    type funcdemo func(int,int)int

    func main(){
    //函数调用
    //test10(10,20)
    //如果使用Print打印函数名是一个地址
    //函数名本身就是一个指针类型数据 在内存中代码区进行存储
    //fmt.Println(test10)

    //自动类型推到创建函数类型
    //f:=test10
    //f(10,20)
    //fmt.Printf("%T",f)
    //直接定义函数类型
    var f func(int,int)
    f=test10
    f(10,20)
    }
  2. 闭包
    函数调用结束时会从内存中销毁
    可以通过匿名函数和闭包 实现函数在栈区的本地化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    func bibao() func() int{
    var a int
    return func() int{
    a++
    rerurn a
    }
    }
    func main(){
    f := bibao()
    for i:=0;i<10;i++ {
    Println(f())
    }
    }
  3. 数组

    1
    2
    var arr [10]int = [10]int{1,2,3,4,5,6,7,8,9,10}
    arr2 :=[...]int{1,2,3}
  4. 随机
    生成随机数代码
    rand.Seed(time.now().UnixNano())
    a := rand.Intn(100)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package main
    import(
    "fmt"
    "math/rand"
    "time"
    )
    func BubbleSort(arr [10]int) [10]int{
    for i := 0; i < len(arr)-1; i++ {
    for j := 0; j < len(arr)-1-i; j++ {
    if(arr[j]>arr[j+1]){
    arr[j],arr[j+1]=arr[j+1],arr[j]
    }
    }
    }

    return arr
    }

    func main(){
    var arr [10]int

    rand.Seed(time.Now().UnixNano())
    for i := 0; i < len(arr); i++ {
    arr[i]=rand.Intn(100)//0-99
    }

    arr =BubbleSort(arr)
    fmt.Println(arr)

    }
  5. 切片Slice
    自动推到类型创建切片: make([] 数据类型,数组名)
    添加切片信息: append(s,34,44,55)
    长度: len(s)
    容量: cap(s)
    与数组区别:数组必须写元素个数。切片不用
    容量扩展:小于1024字节扩展一倍,否则扩展1/4
    切片截取:

    • 切片名[起始下标:]
      slice:=s[2:]
    • 切片名[:结束位置] 不包含结束位置
      slice:=s[:2]
      切片名[起始位置:结束位置]
      slice:=s[2:5]
      切片名[起始位置:结束位置:容量]
      slice:=s[0:2:2]

切片拷贝:

1
2
3
4
5
6
s1:=[]int{1,2,3,4,5}
//var s2 []int//0//0
s2:=make([]int,5)
//将s1切片中的数据拷贝到s2中 s2中要有足够的容量
//使用拷贝操作后s1 s2是两个独立空间 不会相互影响
copy(s2,s1)

1
2
3
4
5
6
7
8
9
10
11
func main(){
s:=make([]int,5)
s[0]=1
//使用append在长度后添加数据
s=append(s,1,2,3)

//在切片打印时 只能打印有效长度中的数据 cap不能作为数组打印的条件
for i := 0; i<len(s);i++ {
fmt.Println(s[i])
}
}
  1. map
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    func map1(){
    //map中数据无序存储,长度自动扩容
    m := make(map[string] int,1)
    m["Alice"] = 10
    m["Mom"] = 30
    m["Dadi"] = 32
    //delete(map,key)
    delete(m, "Dadi")
    delete(m,"Tom") //不会报错
    for i,j :=range m{
    println(i,j)
    }
    }

map作为函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func map2(m map[int]string){
m[1]="Haya"
m[2]="Yuki"
println(len(m)) //输出3
delete(m,0)
println(len(m)) //输出2
}
//map作为函数参数是地址传递 (引用传递)
func main(){
m :=make(map [int]string,1)
m[0] = "Yami"
map2(m)
println(len(m)) //输出2
}

  1. 指针
    两种指针声明方式
    var p *int //nil空指针
    p :=new(int) //new创建好的空间值为数据类型的默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
//指针作为函数参数是地址传递
func swap(a *int, b *int) {
temp:=*a
*a=*b
*b=temp
}

func main(){
a, b := 1,100
swap(&a,&b)
println(a,b)

}

数组指针

1
2
3
4
5
6
7
8
9
10
11

func main(){
var arr [5]int = [5]int{123,2,3,4,5}
//&arr 是 *[5]int 类型
//&arr[0] 是 *int 类型
p:=&arr[0]
fmt.Printf("%T",p)

p2 := &arr
Println(p2[0])
}

切片指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main(){
//切片名本身就是一个地址
var slice []int =[]int{1,2,3,4,5}

fmt.Printf("%p\n",slice)

//等价:p:=&slice//*[]int
var p *[]int //二级指针
p=&slice

//无法通过指针访问切片中的元素
*p=append(*p,6,7,8,9,10)

fmt.Printf("%p\n",slice)
fmt.Println(slice)
}

切片指针传参

1
2
3
4
5
6
7
8
9
10
11
12
func test(s *[]int){
*s=append(*s,4,5,6,)
}

func main() {
s:=[]int{1,2,3}
fmt.Printf("%p\n",s)
//切片指针作为函数参数是地址传递 形参可以改变实参的值
test(&s)
fmt.Printf("%p\n",s)
fmt.Println(s)
}

new 创建切片指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"

func main() {

var p *[]int
fmt.Printf("%p\n",p)
p=new([]int)
fmt.Printf("%p\n",p)

*p=append(*p,1,2,3)

for i,v:=range *p{
fmt.Println(i,v)
}
}