GO 编程学习问题记录

问题一:输出出现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),形参内存空间中底层数组的地址会被覆盖修改为新的扩容后的底层数组地址,而实参无变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值