zoukankan      html  css  js  c++  java
  • Go通关14:参数传递中,值、引用及指针之间的区别

    值类型、引用类型

    1、在Go语言中,值类型和引用类型有以下特点:
    a、值类型:基本数据类型,int,float,bool,string,以及数组和struct
    特点:变量直接存储值,内存通常在栈上分配,栈在函数调用完会被释放

    b、引用类型:指针,slice,map,chan,interface等都是引用类型
    特点:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配,通过GC回收。

    • 严格来说,Go 语言没有引用类型。
    • 但是我们可以把 map、chan、函数、接口、slice 切片, 称为引用类型,这样便于理解。
    • 指针类型也可以理解为是一种引用类型。

    上面我们提到了堆、栈,这里简单介绍下

    内存分配中的堆和栈:

    • (操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
    • (操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

    值类型和指针类型参数示例:

    package main
    
    import "fmt"
    
    func main() {
    	name := "无尘"
    	modify1(name)
    	fmt.Println("name的值为:", name)
    	modify2(&name)
    	fmt.Println("name的值为:", name)
    }
    
    func modify1(name string) { //值类型
    	name = "wucs"
    } 
    func modify2(name *string) { //指针类型
    	*name = "wucs"
    }
    //运行结果:
    //name的值为: 无尘
    //name的值为: wucs
    

    引用类型

    map
    以map类型为参数示例:

    package main
    
    import "fmt"
    
    func main() {
    	m:=make(map[string]int)
    	m["无尘"] = 18
    	fmt.Println("无尘的年龄为",m["无尘"])
    	modify(m)
    	fmt.Println("无尘的年龄为",m["无尘"])
    }
    func modify(p map[string]int)  {
    	p["无尘"] =20
    }
    //运行结果:
    //无尘的年龄为 18
    //无尘的年龄为 20
    
    • 我们看到,函数 modify 的参数类型为 map ,数据仍然修改成功了。
    • 其实,在创建 map 的时候,最终调用的是 runtime.makemap 函数,makemap 函数返回的是一个 *hmap 类型,也就是说返回的是一个指针,所以我们创建的 map 其实就是一个 *hmap。
    • 因为 map 本质上就是个指针,所以通过 map 类型的参数可以修改原始数据。
    // makemap implements Go map creation for make(map[k]v, hint).
    func makemap(t *maptype, hint int, h *hmap) *hmap{
      //省略无关代码
    }
    

    chan
    channel 本质上也是个指针,来看源码:

    func makechan(t *chantype, size int64) *hchan {
        //省略无关代码
    }
    

    可以看到创建的 chan 其实是个 *hchan,所以它在参数传递中也和 map 一样。

    类型的零值

    1. 在 Go 语言中,定义变量可以通过声明或者通过 makenew函数,区别是 make 和 new 函数属于显示声明并初始化。
    2. 如果我们声明的变量没有显示的声明初始化,那么该变量的默认值就是对于类型的零值。
    类型 零值
    数值类型(int、float等) 0
    bool false
    string ""(空字符串)
    struct 内部字段的零值
    slice nil
    map nil
    指针 nil
    函数 nil
    chan nil
    interface nil

    在 Go 语言中,函数的参数传递只有值传递,而且传递的实参都是原始数据的一份拷贝。如果拷贝的内容是值类型的,那么在函数中就无法修改原始数据;如果拷贝的内容是指针(或者可以理解为引用类型 map、chan 等),那么就可以在函数中修改原始数据。

  • 相关阅读:
    Java Json 数据下划线与驼峰格式进行相互转换
    php 将数组转换网址URL参数
    Swagger2常用注解及其说明 (转)
    Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念(转)
    bootstrap.css.map 404
    Git发生SSL certificate problem: certificate ha错误的解决方法
    防火墙禁ping:虚拟机ping不通主机,但主机可以ping虚拟机
    PhpStorm本地断点调试
    Java语言中姐种遍历List的方法总结
    Ubuntu18.04安装mysql5.7
  • 原文地址:https://www.cnblogs.com/isungge/p/15146600.html
Copyright © 2011-2022 走看看