golang的值类型,指针类型和引用类型&值传递&指针传递

栏目: IT技术 · 发布时间: 4年前

内容简介:变量分为值类型,指针类型和引用类型。以如下变量定义和赋值语句为例: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
golang的值类型,指针类型和引用类型&值传递&指针传递

值类型变量和引用类型变量

  • 值类型变量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-pointers-vs-references

欢迎关注我们的微信公众号,每天学习 Go 知识

golang的值类型,指针类型和引用类型&值传递&指针传递

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ASP.NET 2.0入门经典

ASP.NET 2.0入门经典

哈特 / 清华大学出版社 / 2006-8 / 78.00元

该书是Wrox红皮书中的畅销品种, 从初版、1.0版、1.1版到目前的2.0版,已经3次升级,不仅内容更加完善、实用,还展现了.NET 2.0的最新技术和ASP.NET 2.0最新编程知识,是各种初学者学习ASP.NET的优秀教程,也是Web开发人员了解ASP.NET 2.0新技术的优秀参考书。该书与《ASP.NET 2.0高级编程(第4版)》及其早期版本,曾影响到无数中国Web程序员。一起来看看 《ASP.NET 2.0入门经典》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具