【GoLand】Go语言指针操作

294 阅读1分钟

一、Go语言指针使用

1.Go有指针,但是没有指针运算。你不能用指针变量遍历字符串的各个字节。

2.在Go中调用函数的时候,得记得变量是值传递的,可以通过Go的指针做到地址传递

package main

import (
    "fmt"
)

func main () {
    var value uint32
    var pointer *uint32
    pointer = &value
    value = 100
    fmt.Println("value: ", value)
    fmt.Println("pointer: ",*pointer)
    *pointer = 200
    fmt.Println("value: ", value)
    fmt.Println("pointer: ",*pointer)
}

3.结构体指针访问其成员的方式

// go和c不一样,指针也是通过.而非->来访问,使用->会编译报错
package main

import (
   "fmt"
)

type Demo struct {
    a int
    b int
}

func main() {
    p := new(Demo)
    p.a = 1
    (*p).b = 2
    fmt.Println(p)
}

二、Go语言指针运算妙用

1.普通的Go语言指针是无法进行运算的,但是转化成为uintptr之后是可以进行指针运算的,uintptr不会被Go语言当做指针

package main

import (
    "fmt"
    "unsafe"
)

func main () {
    var unit uint32
    var array [5]uint32 = [5]uint32{1, 2, 3, 4, 5}
    base := &array[0]
    value2 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + unsafe.Sizeof(unit)))
    value3 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + 2 * unsafe.Sizeof(unit)))
    value4 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + 3 * unsafe.Sizeof(unit)))
    value5 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(value4)) + unsafe.Sizeof(unit)))
    fmt.Println(base, value2, value3, value4, value5)
    fmt.Println(*base, *value2, *value3, *value4, *value5)
}

2.通过指针操作获取slice切片底层数组的连续内存地址和内容

package main

import (
    "fmt"
    "unsafe"
)

type SliceModel struct {
        array unsafe.Pointer
        len   int
        cap   int
}

func main () {
    var length uint32 = 5
    array := make([]uint32, length)
    fmt.Println(array)
    array[0] = 1
    array[1] = 2
    array[2] = 3
    array[3] = 4
    array[4] = 5
    fmt.Println(array)
    s := (*SliceModel)(unsafe.Pointer(&array))
    base := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(s.array))))
    value2 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + unsafe.Sizeof(length)))
    value3 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + 2 * unsafe.Sizeof(length)))
    value4 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + 3 * unsafe.Sizeof(length)))
    value5 := (*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(base)) + 4 * unsafe.Sizeof(length)))
    fmt.Println(base, value2, value3, value4, value5)
    fmt.Println(*base, *value2, *value3, *value4, *value5)
}

三、参考资料

studygolang.com/articles/29…