内容简介:变量分为值类型,指针类型和引用类型。以如下变量定义和赋值语句为例:output:
一,变量类型
变量分为值类型,指针类型和引用类型。
以如下变量定义和赋值语句为例:
package main import( "fmt" ) func main(){ var a int = 1 p := &a fmt.Printf("%v\n", a) fmt.Printf("%p\n", &a) fmt.Printf("%p\n", p) fmt.Printf("%p\n", &p) }
output:
1 0xc000092000 0xc000092000 0xc00008c010
值类型变量和引用类型变量
- 值类型变量a,值为1,存储变量a的内存地址为0xc000092000
- 指针类型 &a,某个变量的内存地址,即a的地址0xc000092000。
- 引用类型p,某个变量的地址的别名。
- 值为某个变量的内存地址(p的值为变量a的内存地址0xc000092000)
- 其本身作为一个变量也有自己的存储内存地址0xc00008c010。
在golang中故意淡化了指针的概念,我们只需要关注值类型和引用类型就可以
。你在官方介绍中也很少看到指针类型这一概念。
二,golang中的值类型变量和引用类型变量
- 值类型变量:除开slice,map,channel类型之外的变量都是值类型
- 引用类型变量:slice,map,channel这三种
三,值类型和引用类型的区别
我们以值类型struct和引用类型map的区别在哪里。
首先定义两种类型的结构及变量:
type Student1 struct{ Age int32 Name string } type Student2 map[string]int func main(){ var s1 Student1 var s2 Student2 }
1,零值不同
- 指针类型的变量,零值都是nil。
- 值类型的变量,零值是其所在类型的零值。
- int32类型的零值是0
- string类型的零值是""
- bool类型的零值是false
- 符合结构struct类型的零值是其每个成员的零值的组合
fmt.Println(s1) //{0 } fmt.Println(s2) //map[] fmt.Println(s1 == nil) //panic,提示cannot convert nil to type Student1 fmt.Println(s2 == nil) //true
发现map的零值是nil,struct的零值是Student1{0, ""},不是nil,而且struct类型和nil是两种不同的类型,不能比较。
2,变量申明后是否需要初始化才能使用
- 指针类型的变量,需要初始化才能使用。(slice是一个特例,slice的零值是nil,但是可以直接append)
- 值类型的变量,不用初始化,可以直接使用
s1.Name = "minping" s1.Age = 30 fmt.Println(s1) //{30 minping} s2["minping"] = 30 // panic: assignment to entry in nil map fmt.Println(s2)
发现struct声明后可以直接使用直接赋值,但是map就不行,赋值的时候提示我们nil map不能赋值,需要先初始化。
3,初始化方法不同
- 值类型的变量,其实不需要初始化就可以使用。如果有良好的代码习惯,使用前进行初始化也是非常提倡的。
- 基本类型的初始化非常简单:
- var i int; i = 1;
- var b bool; b = true
- var s string; s = ""
- 符合类型struct的初始化有两种:
- s1 = Student1{}
- s1 = new(Student1)
- 基本类型的初始化非常简单:
s1 := Student1{} //{0 } s1 := new(Student1) //&{0 }
- 引用类型的变量,初始化方式也不一样:
- slice类型,用make,new,{}都可以
- map类型,用make,new,{}都可以
- channel类型,只能用make活着new初始化
//map可以用{},make,new三种方式初始化 s2 := Student2{} //map[] s2 := make(Student2) //map[] s2 := new(Student2) //↦[] //slice可以用{},make,new,但是make的时候需要带len参数 type S3 []string s3 := S3{} //[] s3 := new(S3) //&[] s3 := make(S3, 10) //[ ] //channel只能用make或者new type Student4 chan string s4 := new(S4) //0xc000096000 s4 := make(S4) //0xc000082008 s4 := S4{} //编译器报错:invalid type for composite literal: Student4
四,make和new的区别
从上面初始化时用make和new的结果就可以看出来:
- make返回的是对象。
- 对值类型对象的更改,不会影响原始对象的值
- 对引用类型对象的更改,会影响原始对象的值
- new返回的是对象的指针,对指针所在对象的更改,会影响指针指向的原始对象的值。
五,golang没有引用传递,都是值传递
但是拷贝得到的引用类型变量的值,和被传入调用函数的原始引用类型变量的值,是一样的,即指向的是同一个变量的地址
7 type Student struct{ 8 9 Age int 10 } 11 12 func main(){ 13 14 s := Student{30} 15 modify1(s) 16 fmt.Println(s) //{30} 17 18 modify2(&s) 19 fmt.Println(s) //{32} 20 } 21 22 func modify1(s Student){ 23 s.Age = 31 24 } 25 26 func modify2(s *Student){ 27 s.Age = 32 28 }
六,参考
欢迎关注我们的微信公众号,每天学习 Go 知识
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- go 方法接受者 是指针类型和非指针类型的 区别
- golang中值类型/指针类型的变量区别总结
- 7. Go 语言数据类型:指针
- Golang研学:在用好Golang指针类型
- golang 指针类型引起的神奇 bug
- golang中struct 中存放指针类型和值类型有什么区别?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ANSI Common Lisp
Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40
For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!