最近在使用Go的过程当中,遇到了和指针相关的一些问题,通过整理,发现和我最开始理解的指针还不太同样。函数
问题一:在设计cache的时候,须要用到万能类型interface来装各类各样的键值对,有时候有些参数根据须要得使用指针类型,刚开始会这样写测试
func test(a *interface{}){ //do something here ... }
会发现不管我传什么参数都会提示:this
cannot use *mytype as type *interface设计
这个问题与下面实际上是同一个问题。。。指针
问题二:有这么一个需求,定义了一个接口A,在另外一个方法中,我想要设置一个参数是A的实现类型,由于这里会涉及到数据的修改,所以确定是须要传一个指针。所以,想固然的写出了下面的代码code
type myinterface interface{ print() } func test(value *myinterface){ //someting to do ... }
刚开始以为没有问题,可是!在调用test的时候遇到了问题。接口
type mystruct struct { i int } //实现接口 func (this *mystruct) print(){ fmt.Println(this.i) this.i=1 } func main(){ m := &mystruct{0} test(m)//错误 test(*m)//错误 }
*mystruct是实现了myinterface接口的,我但愿test接收的是一个指针类型,所以传*mystruct类型的数据。提示:Cannot use 'm' (type *mystruct) as type *myinterfaceit
说的很明确,没法将*mystruct类型的数据赋值给*myinterface。经过查找各类资料,发如今go语言中,接口自己就是引用类型,换句话说,接口类型自己就是一个指针。对于个人需求,其实test的参数只要是myinterface就能够了,只须要在传值的时候,传*mystruct类型(也只能传*mystruct类型)class
使用下面的代码测试一下test
//一个用于测试的接口 type myinterface interface{ print() } //*mystruct现了myinterface接口 type mystruct struct { i int } type mystruct2 struct { i int } /** 测试一下map类型的指针问题 */ func main() { //测试*mystruct实现效果 m := &mystruct{0} fmt.Printf("address in main is %p\n", m) method1(*m)//method1的参数是mystruct类型 m.print()//m的值并无受到影响 method2(m)//method2的参数是接口类型 m.print()//m的值被修改了 //测试mystruct2实现效果 fmt.Println("##########") m2 := &mystruct2{i:0} fmt.Printf("initial address is %p\n",m2) method3(*m2) m2.print() method2(m2) m2.print() } func method1(m mystruct) { fmt.Printf("address in method1 is %p\n", &m) m.print() } func method2(m myinterface){ fmt.Printf("address in method2 is %p\n",m) m.print() } func method3(m mystruct2){ fmt.Printf("address in method3 is %p\n",&m) m.print() } func (this *mystruct) print(){ fmt.Println(this.i) this.i=1 } func (this mystruct2) print(){ fmt.Println(this.i) this.i=2 }
运行结果以下:
address in main is 0xc42001c090 address in method1 is 0xc42001c098 0 0 address in method2 is 0xc42001c090 1 1 ########## initial address is 0xc42001c0b0 address in method3 is 0xc42001c0b8 0 0 address in method2 is 0xc42001c0b0 0 0
能够看到,使用method2的时候,地址与main函数中的地址是同样的,也就是说,当参数是myinterface的时候,传的是一个引用类型。
另外,mystruct2不管使用哪一种方式都没有改变main函数中的值,这个是由于mystruct2的print函数。
func (this mystruct2) print()
这种声明实际上是
func print(this mystruct2)
能够看出,在print函数中传的是值,而非地址,所以不会影响到外部函数。
在这个过程当中看到过一位大神说的一句:永远不要使用指向interface的指针,这个是没有意义的