Golang:指针

什么是指针?

指针是存储另一个变量的内存地址的变量。

在上面的例子中,变量 b 的值是 156,存储在地址为 0x1040a124 的内存中。变量 a 存储了变量 b 的地址。现在可以说 a 指向 b

声明指针

*T 来表示指向类型 T 的指针变量。

package main

import (  
    "fmt"
)

func main() {  
    b := 255
    var a *int = &b
    fmt.Printf("Type of a is %T\n", a)
    fmt.Println("address of b is", a)
}

& 操作符用来获取一个变量的地址。在上面的程序中,我们将 b 的地址赋给 aa 的类型为 *int)。现在我们说 a 指向了 b。当我们打印 a 的值时,b 的地址将会被打印出来。

指针的空值

指针的空值为 nil

package main

import (  
    "fmt"
)

func main() {  
    a := 25
    var b *int
    if b == nil {
        fmt.Println("b is", b)
        b = &a
        fmt.Println("b after initialization is", b)
    }
}
解引用指针

解引用指针意味着访问指针所指向的变量的值。 指针 a 的解引用表示为:*a

package main  
import (  
    "fmt"
)

func main() {  
    b := 255
    a := &b
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)
}

在上面的程序中,我们将 a 解引用并打印得到的值。和我们预期的一样,程序打印的是 b 的值。

让我们再写一个程序,使用指针改变变量 b 的值。

package main

import (  
    "fmt"
)

func main() {  
    b := 255
    a := &b
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)
    *a++
    fmt.Println("new value of b is", b)
}

在上面的程序中,我们将 a 指向的值自增 1,这样做也改变了 b 的值,因为 a 指向 b。因此 b 的值变为 256

传递指针给函数
package main

import (  
    "fmt"
)

func change(val *int) {  
    *val = 55
}
func main() {  
    a := 58
    fmt.Println("value of a before function call is", a)
    b := &a
    change(b)
    fmt.Println("value of a after function call is", a)
}

在上面的程序中,我们将指向 a 的指针 b 传递给函数 change。在函数 change 内部,通过解引用修改了 a 的值。

不要将指向数组的指针作为参数传递给函数,改用切片

假设我们需要通过函数修改一个数组。一个方法是将数组的指针作为参数传递给函数。

package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  
    (*arr)[0] = 90
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(&a)
    fmt.Println(a)
}

在上面的程序中,将数组 a 的地址传递给函数 modify。在 modify 函数中,通过解引用的方式将数组的第一个元素赋值为 90

a[x](*a)[x] 的简写,因此上面的程序中,(*arr)[0] 可以替换为 arr[0]

package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  
    arr[0] = 90
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(&a)
    fmt.Println(a)
}

尽管这种传递指向数组的指针作为函数的参数并对其进行修改的方式起作用,但这在 Golang 中并不是惯用方式。我们可以使用切片完成同样的事情。

package main

import (  
    "fmt"
)

func modify(sls []int) {  
    sls[0] = 90
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(a[:])
    fmt.Println(a)
}
不支持指针运算

Golang 不支持其他语言如 C 中存在的指针运算。

package main

func main() {  
    b := [...]int{109, 110, 111}
    p := &b
    p++
}

上面的程序会抛出编译错误:invalid operation: p++ (non-numeric type *[3]int)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,495评论 3 44
  • 指针 指针是什么 为了了解指针的概念,我们先来看一个小故事。话说福尔摩斯派华生到威尔爵士居住的城堡去取回一个重要的...
    去留无意hmy阅读 568评论 0 1
  • 我在约定好的那个海边 再次和你相见 你抚摸我的额头 为我戴上花环 留给我一片汪洋似的温柔
    辛安小阅读 604评论 46 57
  • 追梦路上,要抓住青春的尾巴热血一把!
    乐遥阅读 298评论 0 0
  • 现在的你还在暴力加粉吗?是不是加进来的都是微商,都希望买他们的产品?是不是加了都不说话?是不是没有信任?是不是没有...
    陈炬俊阅读 1,012评论 1 2