Go总结
2021-05-23 14:16:50 4 举报
AI智能生成
go知识点学习总结,不断完善中
作者其他创作
大纲/内容
结构
包声明 :package main
引入包:import "fmt"
函数:func main() { }: 是程序开始执行的函数
标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头可以被外部包的代码所使用
赋值
元组赋值:交换变量:x,y=y,x
普通赋值:x = 1 // 命名变量的赋值 *p = true
数组赋值medals := []string{"gold", "silver", "bronze"}
入门
go build helloworld.go 编译文件
原生支持Unicode,它可以处理全世界任何语言的文本
main 包比较特殊。它定义了一个独立可执行的程序
命令行参数
os.Args
os.Args[1:len(os.Args)]
基础语法
一行代表一个语句结束
注释:// /*
字符串连接 :+
关键字 :fallthrough强制执行后面的case代码
打印
fmt.println
fmt.Printf("%d\t%s\n", n, line)
数据类型
rune 类型,代表一个 UTF-8 字符
byte等于uint8 rune等于int32 常用来处理unicode或utf-8字符
uintptr容纳指针
布尔型true或者false
一个字符串是一个不可改变的序列
Channel
切片类型
接口类型(interface)
常量const pi = 3.14159
变量、常量
第一种var v_name v_type 第二种:var v_name = value 第三种:v_name := value
多变量说明:vname1, vname2, vname3 = v1, v2, v3
值类型和引用类型 :引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置
常量: const LENGTH int = 10 ; iota 每次从0加1
匿名变量: data, _ := GetHttpResp()
运算符
算术运算符
+、-、*、/ 、%
关系运算符
!= 、>
逻辑运算符 && || !
位运算符 &, |, 和 ^
赋值运算符 +=
&、*
条件、循环语句
if、if...else 语句、switch 语句
select:会循环检测条件,如果有满足则执行并退出,否则一直循环检测
for 控制:break continue goto 无限循环: for true { }
for _, arg := range os.Args[1:] {
函数
func:函数由 func 开始声明
匿名函数var add = func(a,b int)int{rerurn a + b}
parameter list:参数列表:值传递\引用传递
return_types:返回类型,函数返回一列值;函数返回多个值
go使用动态的栈,跟cpp定长的栈规则不一样 不用关心堆和栈的问题
闭包:func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
} 调用:nextNumber := getSequence()
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
i:=0
return func() int {
i+=1
return i
}
} 调用:nextNumber := getSequence()
/* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
Go 语言函数作为实参 :getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)} 调用fmt.Println(getSquareRoot(9))
return math.Sqrt(x)} 调用fmt.Println(getSquareRoot(9))
function_name:函数名称,函数名和参数列表一起构成了函数签名。
方法:方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针
在Go的panic机制中,延迟函数的调用在释放堆栈信息之前
JSON
编码
MarshalIndent返回可读性更高的slice
data, err := json.Marshal(movies)返回紧凑编码slice
解码
Unmarshal
自由主题
变量作用域
局部、全局、形参 默认值:int 0 float 0 pointer nil
数组
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} ; 索引方式: var c = [...]int{2:3,1:2} 结果:{0,2,3}
向函数传递数组:void myFunction(param []int)
结构体数组 var line3 = [...]image.Point{{0,0},{1,1}}
函数体数组var funarr [2]func(io.Reader)(image.Image,error)
通道数组 var cList = [2]chan int{}
指针
var ip *int /* 指向整型*/ var fp *float32 /* 指向浮点型 */
var ip *int /* 声明指针变量 */
ip = &a /* 指针变量的存储地址 */
ip = &a /* 指针变量的存储地址 */
空指针 nil
指针数组:var ptr [MAX]*int;
slice
语法和数组很像,只是没有固定长度而已
slice由三个部分 构成:指针、长度和容量
如果切片操作超出cap(s)的上限将导致一个panic异常
向函数传递slice将允许在函数内部修改底 层数组的元素
和数组不同的是,slice之间不能比较
slice唯一合法的比较操作是和nil比较 :测试一个slice是否是空的,使用len(s) == 0来判断
内置的make函数创建一个指定元素类型、长度和容量的slice:make([]T, len, cap)
结构体
定义结构体type struct_variable_type struct { }
结构体作为函数参数 func printBook( book Books ) {}
结构体指针 var struct_pointer *Books
p := Point{1, 2}
嵌入匿名成员:type Circle struct { Point Radius int }
切片
定义简化版的动态数组:var identifier []type 或者slice1 := make([]type, len)
初始化:s :=[] int {1,2,3 } s := arr[:] s := arr[startIndex:]
len() 和 cap() 函数 空(nil)切片
截取numbers[1:4] ;删除最后一个元素a = a[:len(a) - 1]
追加 numbers = append(numbers, 0) copy(numbers1,numbers)
高效的要点是减少内存分配
语言范围
range: for _, num := range nums {
Map
定义ages := make(map[string]int)
ages := map[string]int{ "alice": 31, "charlie": 34, }
*查看元素在集合中是否存在 capital, ok := countryCapitalMap [ "American" ]
删除 delete(countryCapitalMap, "France")
但是map中的元素并不是一个变量,因此我们不能对map的元素进行取址操作
类型转换
type_name(expression) :mean = float32(sum)/float32(count)
type 类型名字 底层类型
语言接口
type interface_name interface
错误处理
定义:type error interface {Error() string}
func Sqrt(f float64) (float64, error) {
并发
go 函数名( 参数列表 )
通道(channel):ch <- v ;v := <-ch // 从 ch 接收数据
// 并把值赋给 v// 把 v 发送到通道 ch
// 并把值赋给 v// 把 v 发送到通道 ch
声明通道:ch := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从通道 c 中接收
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从通道 c 中接收
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 把 sum 发送到通道 c
}
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 把 sum 发送到通道 c
}
通道缓冲区: ch := make(chan int, 2) ;ch <- 1
ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch)
ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch)
遍历与关闭:for i := range c {} close(c)
原子操作:sync/atomic : atomic.AddUint64(&total,i)
主函数返回时,所有的goroutine都会被直接打断
一个基于无缓存Channels的发送操作将导致发送者goroutine阻塞
竞态
互斥锁:sync.Mutex
读写锁:sync.RWMutex
检测器:race detecotr
工具包
go env 显示环境:设置linux编译:set GOOS=linux
set GOARCH=amd64
set GOARCH=amd64
下载包:go get github.com/golang/lint/golint
构建包:go build
查询包:go list github.com/go-sql-driver/mysql
反射
reflect.Type:表示一个Go类型
reflect.Value:可以装载任意类型的值.
对于性能关键路径的函数,最好避免使用反射
0 条评论
下一页