问题一:输出出现d%!(NOVERB)%!(EXTRA int=37)
问题描述:
在输出时出现
{学生d%!(NOVERB)%!(EXTRA int=37) 6 20.318687664732284}
代码:
func main() {
n := fmt.Sprintf("学生d%", rand.Intn(100))
fmt.Println(n)
}
求解答!
问题二:接口
接口的理解
如何理解接口?——>【接口是一组方法的集合】
举例:定义接口鸭子,实现方法嘎嘎叫
现有只小鸡,厉害到也会鸭叫,也就是实现了嘎嘎叫的方法,因此可以把这只鸡视为鸭子类型,也就可以在要求用鸭子接口的地方用这只鸡。
type duck interface {
gaga()
}
type chicken int
func (c chicken) gaga() {
fmt.Printf("嘎嘎")
}
func main() {
var c chicken
duck.gaga(c)
}
接口的一个方法传递指针,另一个方法传递值
heap接口的push函数与pop函数,push函数传递的是指针,然后就报错了。
func (h *Intheap) Push(x interface{}) {
*h = append(*h, x.(int)) //x.(int)类型断言,如果不x为int型则报panic
fmt.Printf("append后h的地址为%p", h)
}
func (h Intheap) Pop() interface{} {
old := h
n := len(h)
x := old[n-1]
h = old[:n-1]
return x
}
未解决,求解答!
问题三:slice 作为函数参数传递
push函数:
func (h Intheap) Push(x interface{}) {
h = append(h, x.(int)) //x.(int)类型断言,如果不x为int型则报panic
}
heap.Push(h, 9)
调用push函数后,发现并没有预期中将9加入切片h中
h的地址为0xc00000a168
append后h的地址为0xc00000c420[1 2 6]
解决:
slice作为参数,如果以值的形式传递,确实可以在函数内部修改数组,但前提是,函数内部slice不会扩容,如果函数内部slice会扩容,那还是得传slice指针进去,如下面代码。
func (h *IntHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
参考:https://blog.csdn.net/u013536232/article/details/105547626
对slice的理解不够,需要区分原slice(实参)与副本slice(形参)
slice
slice看起来像数组,实际上是一个结构体,在源码中的数据结构是:
type slice struct {
array unsafe.Pointer
len int
cap int
}
指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。
区分对形参进行修改 / 扩容
副本中的array指针与原slice指向同一个地址,所以当修改副本slice的元素时,原slice的元素值也会被修改。但是如果修改的是副本slice的len和cap时,原slice的len和cap仍保持不变。
形参的底层数组指针与实参相同,当修改形参slice时,实参也会发生改变,但如果对形参进行扩容(append),形参内存空间中底层数组的地址会被覆盖修改为新的扩容后的底层数组地址,而实参无变化。