6. golang的指针运算 @H_197_3@

Go语言的语法上是不支持指针运算的,所有指针都在可控的一个范围内使用,没有C语言的*void然后随意转换指针类型这样的东西。最近在思考Go如何操作共享内存,共享内存就需要把指针转成不同类型或者对指针进行运算再获取数据。对Go语言内置的unsafe模块做了一个实验,发现通过unsafe模块,Go语言一样可以做指针运算,只是比C的方式繁琐一些,但是理解上是一样的。 @H_450_7@

@H_450_7@

package main

import "fmt"
import "unsafe"

type Data struct {
	Col1 byte
	Col2 int
	Col3 String
	Col4 int
}

func main() {
	var v Data

	fmt.Println(unsafe.Sizeof(v))

	fmt.Println("----")

	fmt.Println(unsafe.Alignof(v.Col1))
	fmt.Println(unsafe.Alignof(v.col2))
	fmt.Println(unsafe.Alignof(v.Col3))
	fmt.Println(unsafe.Alignof(v.Col4))

	fmt.Println("----")

	fmt.Println(unsafe.offsetof(v.Col1))
	fmt.Println(unsafe.offsetof(v.col2))
	fmt.Println(unsafe.offsetof(v.Col3))
	fmt.Println(unsafe.offsetof(v.Col4))

	fmt.Println("----")

	v.Col1 = 98
	v.Col2 = 77
	v.Col3 = "1234567890abcdef"
	v.Col4 = 23

	fmt.Println(unsafe.Sizeof(v))

	fmt.Println("----")

	x := unsafe.Pointer(&v)

	fmt.Println(*(*bytE)(X))
	fmt.Println(*(*int)(unsafe.Pointer(uintptr(X) + unsafe.offsetof(v.col2))))
	fmt.Println(*(*String)(unsafe.Pointer(uintptr(X) + unsafe.offsetof(v.Col3))))
	fmt.Println(*(*int)(unsafe.Pointer(uintptr(X) + unsafe.offsetof(v.Col4))))
}

unsafe模块的文档中提到几条转换规则,理解了以后就很容易做指针运算了: @H_450_7@

  1. A pointer value of any type can be converted to a Pointer.
  2. A Pointer can be converted to a pointer value of any type.
  3. A uintptr can be converted to a Pointer.
  4. A Pointer can be converted to a uintptr

对于unsafe模块还需要看一下。 @H_450_7@