This is a creation in Article, where the information may have evolved or changed.
The pointer type of the GO language
Simply speaking, the pointer type of the go language is the same as the pointer type usage for C/s + +, except for security reasons, the Go language adds some restrictions, including the following:
- Different types of pointers cannot be converted to each other, such as *int, int32, and Int64
- Any normal pointer type *t and UINTPTR cannot be converted to each other
- Pointer variables cannot be operated on, such as + + in C + +,--operations
For example
package mainimport ( "fmt" )func main() { i1 := int(1) i2 := int32(1) i3 := int64(1) p1 := &i1 p2 := &i2 p3 := &i3 p1 = (* int)(p2) p1 = (* int)(p3) p2 = (* int32)(p1) p2 = (* int32)(p3) p3 = (* int64)(p1) p3 = (* int64)(p2) p1 = p1 + 8 fmt.Printf("p1=%p,p2=%p,p3=%p\n", p1, p2, p3);}
The go compiler will error all the pointer type conversions, as well as the pointer operation error, as follows:
$ go build main.go# command-line-arguments./main.go:14: cannot convert p2 (type *int32) to type *int./main.go:15: cannot convert p3 (type *int64) to type *int./main.go:17: cannot convert p1 (type *int) to type *int32./main.go:18: cannot convert p3 (type *int64) to type *int32./main.go:20: cannot convert p1 (type *int) to type *int64./main.go:21: cannot convert p2 (type *int32) to type *int64./main.go:23: invalid operation: p1 + 8 (mismatched types *int and int)
But the go language also provides an unsafe. Pointer package, with its help, all operations are feasible. Note, however, that these operations are unsafe because the functions provided inside the unsafe package break the security mechanisms of the go type system and memory management, requiring the user to be very careful, which is what the package name is called unsafe.
Unsafe package
Package unsafe provides the following two important pointers related functions:
- Any type of pointer can be converted to unsafe. Pointer type, and vice versa
- A UIntPtr value can be converted to unsafe. Pointer type, and vice versa
The two extensions are custom-scaled for the limitations of the front-facing pointers, in contrast to the previous restrictions on the use of the go language for pointers.
By first, the conversion between the pointer types is possible, and the original pointer type is first converted to unsafe. Pointer, and then put the unsafe. The pointer is converted into a target pointer type.
Then through the second, making the pointer operation possible, first convert the original pointer to unsafe. Pointer, then put the unsafe. The pointer is converted into UINTPTR, then the numerical operation is performed, and the value after the operation is converted back to unsafe. Pointer, finally put the unsafe. pointer converts the corresponding raw data pointer back.
Here is a supplement to the unsafe. Pointer and uintptr Two types are explained separately two sentences:
- Unsafe. Pointer is a pointer type, and the value pointed to cannot be parsed, similar to the (void *) in C/s + +, only that it is a pointer, but what is pointed to does not know.
- UIntPtr is an integer type whose width is large enough to store a pointer-type data; since it is an integer class type, it can certainly be calculated.
To cite an example of use
package mainimport ( "fmt" "unsafe")func main() { var ii [4]int = [4]int{ 11, 22, 33, 44 } var p0 * int = &ii[0] // p0 point to first element var p1 unsafe.Pointer = unsafe.Pointer(p0) // convert (* int) to unsafe.Pointer var p2 uintptr = uintptr(p1) // convert unsafe.Pointer to uintptr p2 += 8 // computing uintptr with plus 8, i.e, the next element address var p3 unsafe.Pointer = unsafe.Pointer(p2) // convert uintptr back to unsafe.Pointer var p4 * int64 = (* int64)(p3) // convert unsafe.Pointer to another type pointer, (* int64) fmt.Printf("*p0=%d,*p4=%d\n", *p0, *p4);}
In this example, an int array is defined, then a pointer to the first element is defined, followed by the pointer, which points to the next element, and finally prints the value of the next element in int64 format.
$ go build && ./main *p0=11,*p4=22
About unsafe. Detailed description of the pointer
Please refer to the official documentation
Https://golang.org/pkg/unsafe/#Pointer