go语言学习笔记+源码

基本结构

1.import 关键字 引用其他的包:

import(“fmt”)
#通常写成
import (
	“fmt”
	)

2.golang的执行程序, packmain,只有一个main入口函数

3.包中函数调用:

a> 同一包中的函数,直接调用;

b> 不同包中的函数, 通过包名+点+函数名 直接调用 dev.add

4包访问控制规则

a>大写意味着函数可导出

b>小写意味着函数/变量是私有的, 包外部不能访问

package main
import (
	a “fmt”   #a是包的别名 可调用保内函数
	a “bu”
	_ “bus”   #_是导入一个包但是不想用里面的函数, 只会执行里面的初始化函数
	)
	func main(){
		fmt.Println(“res=”,a.add)
	}

函数声明

栗子:

func add(a int ,b intint{#一个返回值
}
func add(a int ,b int)(intint{#两个返回值
}

常量

1.使用const修饰常量, 代表永远是只读的, 不可修改.

2.const 只能修饰 boolean、number(int相关类型、浮点型、complex)、string.

3.语法:const identifier[type] = value . type 可被省略

举个栗子:

const bu string = "abu"
const bu ="abu"
const p = 3.1415926
const a = 9/3
const res = getValue()  #错误  不能通过函数动态的获取
优雅写法:
	const(
	a = 0
	b = 1
	c = 2
	)
专业写法:
	const(
	a = iota
	b
	c
	)
	

值类型和引用类型

1.值类型 变量直接储存值, 内存在栈中分配.

2.引用类型:变量储存的是一个地址, 这个储存地址的最终值.内存实在堆上分配, 通过GC回收

流程控制

switch

var int a=0
switch a{
case0,2,6:
fmt.println(”显示a")
fallthrough         #即时匹配成功也会强制向下走,breack在go中可省略
case:1:
fmt.printin("显示b")
default:          #默认值
}
package main

import "fmt"

func main() {
	 a :=100
	for i:=0; i<a;i++  {
		if i %2 ==1 {
			switch i {
			case 1:
				fmt.Println("i=",i)
			case 11:
				fmt.Println("i=",i)
			case 25,27,31:
				fmt.Println("i=",i)

			}

		}
	}
	
}
#猜数字
package main

import (
	"fmt"
	"math/rand"
)

func main() {
	n :=rand.Intn(100)
	for  {
		var input int
		fmt.Scanf("%d\n",&input)
		flag := false
		switch {
		case input ==n:
			fmt.Println("答对了")
			flag = true
		case input>n:
			fmt.Println("大了")
		case input

for range

package main

import "fmt"

func main() {
	var str string =  "阿布呵呵呵"
	for i,v :=range str{
		if i >3 {
			continue
		}
		fmt.Printf("index[%d] val[%c]",i,v)
	}

}
输出---------------------------
index[0] val[阿]index[3] val[布]

字符串

字符串检测

package main

import (
	"fmt"
	"strings"
)

func test(str string){
	res :=strings.HasPrefix(str,"https://")
	if res{
		fmt.Println(str)
	}else {
		fmt.Println("没有匹配到")
	}
}


func main() {
	str :="http://www.baidu.com"
	test(str)
	
}

字符串替换

package main

import (
	"fmt"
	"strings"
)

func main() {
	str :="abuabuabuabuuuuuuu"
	res := strings.Replace(str,"abu","kun",1)
	fmt.Println(res)
}

时间

package main

import (
	"fmt"
	"time"
)

func test(){
	time.Sleep(time.Millisecond*100)
}


func main() {


	//now := time.Now()//获取当前时间
	start := time.Now().UnixNano()
	test()
	end := time.Now().UnixNano()
	fmt.Println((end - start)/1000)
}

指针

类型前面加* 声明称指针类型

package main

import "fmt"

func test(a *string)  {
	 *a = "10000"  #将传入的地址重新赋值
	return
}



func main() {
	a :="15"

	test(&a)
	fmt.Println(a)#传入地址
}
package main
//交换值
import (
	"fmt"
)
func sec(a *int , b *int){  //*代表指针
	tem := *a  //* 表示取地址所对应的值
	*a = *b
	*b = tem

	return
}

func main() {
	a1 :=10
	b1 :=20
	sec(&a1,&b1)//&带表串地址进去
	fmt.Println("a1=",a1)
	fmt.Println("b1=",b1)
}

函数

package main

func add(a,b int)int{
	return a+b
}
func main() {
	c := add
	println(c(200,300))
输出--------------
500
package main

import "fmt"

type bu_func func(int,int) int  #自定义函数类型
func add(a,b int)int{
	return a+b
}
func res(buFunc bu_func,a,b int) int  {
	return buFunc(a,b)
}
func main() {
	c := add
	sum := res(c,200,300)
	fmt.Println(sum)
}

返回值命名和接收

package main

import "fmt"


func add(a,b int)(sum,avg int){
	sum = a+b
	avg = (a+b)/2
	return
}
func main() {
	sum,_ :=add(201,300)  #"_"表示忽略接受该返回值
	fmt.Println(sum)

}

可变参数

package main

import "fmt"

func test(a int,arg...int)(sum int){  #这里必须有返回值, 否则报错too many arguments to return

	for i:=0;i<len(arg) ;i++  {
		sum +=arg[i]
	}
	return 
}


func main() {
	sum :=test(20,30,40)#报错 test(20, 30, 40) used as value
	fmt.Println(sum)
}

defer

1.当函数返回时执行defer语句, 可以用来做资源清理

2.多个defer语句会以先进后出的方式执行

3.defer 中的变量,在defer 声明的时候已经确定了

package main

import "fmt"

func main() {
	 a :=1
	defer fmt.Println(a)
	 a++
	fmt.Println(a)
	
}
输出
2
1

匿名函数

package main

import "fmt"

func test() int{
---------------------------------------
	res := func(a1 ,b1 int)  int {
		return a1 +b1
	}(20,30)  //两种调用方式
	return res
	-------------------------------------
		res := func(a1 ,b1 int)  int {
		return a1 +b1
	}  //两种调用方式
	return res(20,30)
}


func main() {
		r := test()
		fmt.Println(r)
}

内置函数

close:用来关闭channel

len:用来求长度, 比如string, array,slice,map, channel

new :用来分配内存,主要用来分配值类型

make:用来分配内存, 主要用来分配引用类型

append:用来追加元素到数组、slice中

panic 和recover ,用来做错误处理

闭包

package main

import "fmt"

func bu()func(int)int{
	var x int
	return func(d int) int {
		x += d
		return x
	}
}




func main() {
	f :=bu()
	fmt.Println(f(1))
	fmt.Println(f(3))
}
输出  
1
4
package main

import (
	"fmt"
	"strings"
)

func suffix(a string) func( name string) string{
	return func(name string) string {
		if strings.HasPrefix(name,a) ==false {
			return name+a
		}
		return name
		}
}



func main() {
	s1 :=suffix(".jpg")
	fmt.Println(s1("bu"))

}
输出
bu.jpg

#闭包中的变量会一直存在, 对内存开销较大

数组

arr [5]int = [...]int {1,2,3} #初始化
package main

import "fmt"

func test(arr *[5]int ){   #长度一定一致
	(*arr)[1] = 200
	return
}
func test1(arr [5]int){
	for index,val :=range arr{
		fmt.Println(index)
		fmt.Println(val)
		fmt.Println("---")
	}
func main() {
	var arr [5]int  #长度一定一致
	arr[0] = 100
	fmt.Println(arr)
	test(&arr)
	fmt.Println(arr)
	test1(arr)
}
输出
[100 0 0 0 0]
[100 200 0 0 0]
0
100
---
1
200
---
2
0
---
3
0
---
4
0
---

切片

var test []int //定义空的
var test = []int{3,4,5,6} //初始化
test :=[]int{3,4,5,6}  //简短模式+初始化

test :=[]int{5:25}  //赋值

基于数组创建切片

package main

import "fmt"

func main() {
	var arr [10]int =[10]int{1,2,3,4,6,7}
	//var myslice []int = arr[:5]	//基于前5个元素创建切片
	//var myslice []int = arr[:5]	//基于第5个元素开始的所有元素创建切片
	var myslice []int = arr[:]     //基于所有元素创建切片
	fmt.Println(myslice)
	for _,v := range myslice {
		fmt.Println(v)
	}
	
}
输出:
[1 2 3 4 6]
1
2
3
4
6

直接创建

package main

import "fmt"

func main() {
	//myslice := make([]int,5)		//创建一个初始值个数为5的数组切片,元素初始值为0
	//输出:[0 0 0 0 0]
	//myslice := make([]int,5,10)		//创建一个初始值个数为5的数组切片,元素初始值为0,并预留10个元素的储存空间
	//输出:[0 0 0 0 0]
	myslice :=[]int{1,2,6,4,5}		//创建并初始化包含5个元素的数据切片
	//输出:[1 2 3 4]
	fmt.Println(myslice)
	for i :=0; i<len(myslice);i++ {
		fmt.Println(myslice[i])
		//输出
		//1
		//2
		//3
		//4
		//5

	}
	for _, v :=range myslice{
		fmt.Println(v)
		//输出
		//1
		//2
		//6
		//4
		//5
	}
}、、,

map

第一种方式
var test【变量名】 map[key的类型]值的类型  #声明
test = make(map[key值类型]值类型,空间大小)  #分配空间
#声明后map不能直接赋值, 需分类空间后
第二种方式
 test := map[string]string{
	test['nu1'] : '北京'
	test['nu2'] : '上海'
	test['nu3'] : '深圳'
}
test["nu4"] = "天津"、
第三种方式
test :=make(map[string]string)
test["nu1"] = "北京"
test["nu2"] = "上海"

结构体

你可能感兴趣的:(go)