一、 多赋值和短变量声明
range复用临时变量
func main() {
// 切片
//testStringsJoin()
var ch byte = 65
var letter byte = '\x41'
fmt.Printf("ch = %c, letter = %c\n", ch, letter)
p := []int{1, 4, 2, 3, 5, 6, 7, 9, 8, 0}
wg := sync.WaitGroup{} // 同步控制
for i := 0; i < len(p); i++ {
wg.Add(1)
go func(i int) {
fmt.Println(p[i])
wg.Done()
}(i)
}
//for i := range p {
// wg.Add(1)
// go func(i int) {
// fmt.Println(p[i])
// wg.Done()
// }(i)
//}
// 多个goroutine共享同一个i, rang复用临时变量
//for i := range p {
// wg.Add(1)
// go func() {
// fmt.Println(p[i])
// wg.Done()
// }()
//}
wg.Wait()
}
使用命令查看程序是否存在数据竞态情况
go run -race main.go
分析结果
2、defer陷阱
返回值因形式不同而不同
func f1() (y int) {
defer func(y *int) {
*y++
}(&y)
return 5
}
func f2(x int) (y int) { //x=5
defer func() {
y++
}()
return x
}
// 显式变量
func f3() (y int) {
defer func(y int) {
y++
}(5)
return y
}
// 1
func f6() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 1
}
// 5
func f5() (r int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
// 闭包 val= val+2
func f4() (val int) {
defer func() {
val = 5 + val
}()
return 2
}
结论:
3、切片困惑-数组
4、切片
func testArr() {
var intarr []int = []int{1, 4, 2, 4, 5, 7}
var slice []int = intarr[1:3]
slice2 := intarr[1:3]
fmt.Println(slice)
fmt.Println(len(slice)) // 切片元素个数
fmt.Println(cap(slice)) // 切片容量 动态变化
fmt.Println(slice2) //
// 追加是底层扩容数组
fmt.Println(intarr)
slice3 := append(slice2, 88, 99)
fmt.Println(slice3)
fmt.Println(intarr)
// copy
var b []int = make([]int, 10)
copy(b, intarr)
fmt.Println(b)
}
5、值、指针与引用
go支持的是值传递