zoukankan      html  css  js  c++  java
  • Golang 指针理解

    0x00 指针地址和指针类型

    一个变量对应一个保存了变量对应类型值的内存空间,一个指针的值是另一个变量的地址,指针变量可以指向任何一个值的内存地址。

    取地址符号 &
    在指针类型前加上 * 号,可以获取指针所指向的内容,它是一个类型更改器,使用一个指针引用一个值称为间接引用。

    prt := &v    // v 的类型为T
    

    v 表示被取地址的变量,prt 接收 v 的地址,prt 的类型为 *T,称为 T 的指针类型。

    0x01 从指针获取指针指向的值

    使用 & 对变量进行取地址之后,获得这个变量的指针,可以对指针使用 * 号来获取这个指针指向的值,称为指针取值。

    temp := "test content"
    prt := &temp
    fmt.Println(*prt)   // 打印 test content
    

    变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

    对变量进行取地址(&)操作,可以获得这个变量的指针变量。
    指针变量的值是指针地址。
    对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。

    0x02 使用指针修改值

    使用 * 对指针指向的值进行修改和操作

    x, y := 1, 2
    fmt.Println(x, y)  // 1 2
    j, k := &x, &y
    *j, *k = *k, *j
    fmt.Println(x, y)  // 2 1
    

    * 操作符的根本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值;当操作在左值时,就是将值设置给指向的变量。

    如果只是对引用的指针进行交换,那么对被引用的变量,值和地址都是不会影响,受影响的只是应用的指针。

    x, y := 1, 2
    fmt.Println(x, y)  // 1 2
    j, k := &x, &y
    j, k = k, j
    fmt.Println(x, y)    // 1 2
    fmt.Printf("x : %p, y :  %p 
    ", &x, &y)  // x : 0xc00001a088, y :  0xc00001a090
    fmt.Printf("j : %p, y :  %p 
    ", j, k)  //j : 0xc00001a090, y :  0xc00001a088
    

    x, y 值和地址都不影响,指针j, k 交换之后,j, k 的值交换了。

    0x03 返回函数中局部变量

    在Go语言中,返回函数中局部变量的地址也是安全的,例如下面的代码,调用f函数时创建局部变量v,在局部变量地址被返回之后依然有效,因为指针p依然引用这个变量

    var p = f()
    
    func f() *int {
        v := 1
        return &v
    }
    

    0x04 使用 new() 创建指针

    	temp := new(int)
    	*temp = 123
    	fmt.Println(*temp)  // 123
    	fmt.Println(temp)  //  0xaabb
    

    0x05 flag包的指针技术

    指针是实现标准库中flag包的关键技术,它用来实现命令行的标志解析。
    例子:

    package main
    
    import (
        "flag"
        "fmt"
        "strings"
    )
    
    var n = flag.Bool("n", true, "print test")
    var sep = flag.String("s", " ", "separator")
    var test = flag.String("test", " ", "测试")
    
    func main() {
        flag.Parse()
        fmt.Println(strings.Join(flag.Args(), *sep))
        if *n {
            fmt.Println(*test)
        }
    }
    

    运行

    $ go run main.go --help
    Usage of /var/exe/main:
      -n	print test
      -s string
        	separator (default " ")
      -test string
        	测试 (default " ")
    exit status 2
    $ go run main.go -s "+"  --test 测试文本 a bc def 123
    a+bc+def+123
    $ go run main.go -s "+" -n --test 测试文本 a bc def 123
    a+bc+def+123
    测试文本
    
  • 相关阅读:
    JVM的生命周期、体系结构、内存管理和垃圾回收机制
    JVM的ClassLoader过程分析
    MySQL Cluster配置概述
    tomcat下bin文件夹下shell文件分析
    Eclipse环境下使用Maven注意事项
    mysql服务器的字符集
    判断文件中是否存在中文字符
    Tomcat/JSP中文编码配置
    Java内存泄露的原因
    Python 开发轻量级爬虫08
  • 原文地址:https://www.cnblogs.com/nnylee/p/11512487.html
Copyright © 2011-2022 走看看