go * 和 &有什么区别?

类型 *T 是指向 T 类型值的指针。其零值为 nil。

var p *int

& 操作符会生成一个指向其操作数的指针。

i := 42
p = &i
  • 操作符表示指针指向的底层值。
fmt.Println(*p) // 通过指针 p 读取 i
*p = 21         // 通过指针 p 设置 i

示例:

package main

import "fmt"

func main() {
	i, j := 42, 2701

	p := &i         // 指向 i
	fmt.Println(*p) // 通过指针读取 i 的值
	*p = 21         // 通过指针设置 i 的值
	fmt.Println(i)  // 查看 i 的值

	p = &j         // 指向 j
	*p = *p / 37   // 通过指针对 j 进行除法运算
	fmt.Println(j) // 查看 j 的值
}

切片的容量怎么计算的?

官方解释:
切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。

package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)

	// 截取切片使其长度为 0
	s = s[:0]
	printSlice(s)

	// 拓展其长度
	s = s[:5]
	printSlice(s)

	// 舍弃前两个值
	s = s[2:]
	printSlice(s)
	
	s = s[:0]
	printSlice(s)
	
	s = s[:2]
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

结果:

len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=5 cap=6 [2 3 5 7 11] //它为什么会有值?  因为官方这个解释?:“切片并不存储任何数据,它只是描述了底层数组中的一段。”,看下一行输出,显然有点说不过去,那这里是为什么呢?
len=3 cap=4 [5 7 11]  //5算是第一个元素,底层数组是[2 3 5 7 11 13],那么从5开始到13有4个元素,所以容量是4
len=0 cap=4 []
len=2 cap=4 [5 7]

关于print、printf、println

print:打印不换行
println:打印换行
printf:搭配占位符使用,打印占位符

<<、>>左移和右移
a<<2 a乘以4
a>>1 a除以2