Go学习笔记:Go的指针、interface

最近在使用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的指针,这个是没有意义的

相关文章
相关标签/搜索