来源:自学PHP网 时间:2019-08-07 16:47 作者:小飞侠 阅读:次
[导读] golang中值类型/指针类型的变量区别总结...
前言 值类型:所有像int、float、bool和string这些类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过 &i 获取变量 i 的内存地址 指针类型:简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增加了一些限制,包括如下几条:
下面将给大家详细介绍golang中值类型/指针类型的变量的一些区别,下面话不多说了,来一起看看详细的介绍吧。 值类型的变量和指针类型的变量 先声明一个结构体: type T struct { Name string } func (t T) M1() { t.Name = "name1" } func (t *T) M2() { t.Name = "name2" }
下面声明一个 T 类型的变量,并调用 t1 := T{"t1"} fmt.Println("M1调用前:", t1.Name) t1.M1() fmt.Println("M1调用后:", t1.Name) fmt.Println("M2调用前:", t1.Name) t1.M2() fmt.Println("M2调用后:", t1.Name) 输出结果为: M1调用前: t1 M1调用后: t1 M2调用前: t1 M2调用后: name2 下面猜测一下go会怎么处理。 先来约定一下:接收者可以看作是函数的第一个参数,即这样的: 当调用 当调用 类型的变量这两个方法都是拥有的。 下面声明一个 *T 类型的变量,并调用 t2 := &T{"t2"} fmt.Println("M1调用前:", t2.Name) t2.M1() fmt.Println("M1调用后:", t2.Name) fmt.Println("M2调用前:", t2.Name) t2.M2() fmt.Println("M2调用后:", t2.Name) 输出结果为: M1调用前: t2 M1调用后: t2 M2调用前: t2 M2调用后: name2
*T 类型的变量也是拥有这两个方法的。 传给接口会怎样? 先声明一个接口 type Intf interface { M1() M2() } 使用: var t1 T = T{"t1"} t1.M1() t1.M2() var t2 Intf = t1 t2.M1() t2.M2() 报错:
T does not implement Intf (M2 method has pointer receiver)
t1 是有 简单来说,按照接口的理论:传过去【赋值】的对象必须实现了接口要求的方法,而t1没有实现 当把 如果声明一个方法 fun 嵌套类型 声明一个类型 S,将 T 嵌入进去 type S struct { T } 使用下面的例子测试一下: t1 := T{"t1"} s := S{t1} fmt.Println("M1调用前:", s.Name) s.M1() fmt.Println("M1调用后:", s.Name) fmt.Println("M2调用前:", s.Name) s.M2() fmt.Println("M2调用后:", s.Name) fmt.Println(t1.Name) 输出: M1调用前: t1 M1调用后: t1 M2调用前: t1 M2调用后: name2 t1 将 T 嵌入 S, 那么 T 拥有的方法和属性 S 也是拥有的,但是接收者却不是 S 而是 T。 所以 最后 t1 的值没有改变,因为我们嵌入的是 T 类型,所以 S{t1} 的时候是将 t1 拷贝了一份。 假如我们将 s 赋值给 Intf 接口会怎么样呢? var intf Intf = s intf.M1() intf.M2() 报错:
还是
下面嵌入 *T 试试: type S struct { *T } 使用时这样: t1 := T{"t1"} s := S{&t1} fmt.Println("M1调用前:", s.Name) s.M1() fmt.Println("M1调用后:", s.Name) fmt.Println("M2调用前:", s.Name) s.M2() fmt.Println("M2调用后:", s.Name) fmt.Println(t1.Name) M1调用前: t1 M1调用后: t1 M2调用前: t1 M2调用后: name2 name2 惟一的区别是最后 t1 的值变了,因为我们复制的是指针。 接着赋值给接口试试: var intf Intf = s i ntf.M1() intf.M2() fmt.Println(s.Name) 编译没有报错。这里我们传递给 intf 的是值类型而不是指针,为什么可以通过呢? 拷贝 s 的时候里面的 T 是指针类型,所以调用
总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对自学php网的支持。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com