Unsafe.Pointer illustration of Go

Unsafe.Pointer is a type that can be seen everywhere: map, channel, interface, slice, etc. Unsafe.Pointer is also a reference to anything unsafe.

Unsafe. a Pointer is a Pointer. Even though unsafe, what the heck is that?

Unsafe.Pointer, “unsafe Pointer” for Go.

01

What is a variable

Before we get to Pointers, it’s important to understand what a “variable” is. A variable is simply the name of a memory address, which may sound strange: a pointer is not an address?

Listen to me: this address is not that address. Normally, we want to store data in computer memory. What do we do?

We definitely say: “Computer, address 0x0201 memory a number of 100”. On this sentence, although it is rough, in fact in the computer really do so. Then we go on to say: “What to save in 0x0202, what to save in 0x0203, change the value in 0x0203 to the value in 0x0201…”

These “0x0201”, “0x0202”, “0x0203″… Are these numbers hard to remember? Is it too much to write code? “0x0201” I’ll call it X, “0x0202” I’ll call it Y, and “0x0203” I’ll call it Z…

So “computer, address 0x0201 memory a number of 100”. It becomes var x int =100. And this this code name is the variable.

X0201 address 0 = = = = = = = = = = = = = = = = "1000 x0201 address X = = = = = =" 100"Copy the code

Sure enough, any problem in the computer world can be solved by adding an intermediate layer.

Finally, the computer stores in memory the correspondence between the code name and the variable address.

02

What is a pointer

In our mind, the concept of pointer is actually an object that holds a memory address, which may be another object, function or structure.

This is true, but it is important to understand the relationship between Pointers and variables.

In the generic pointer, since the pointer is just an address and the underlying implementation is an unsigned int, assignment between Pointers and operation between types of computation are common in C.

The following code takes a quick look to see if you know the output.

#include "stdio.h"int main(int argc, char const *argv[]){         char c = 'b';         int i = 1000;         char *cp;         int *ip;   // Normal assignment of pointer cp = &c; ip = &i;printf("cp[%p]\n", cp); //cp[0x7ffee904275f] printf("ip[%p]\n", ip); // IP [0x7ffEE9042758] // cp = cp + 1; ip = ip + 1;printf("cp[%p]\n", cp); //cp[0x7ffee9042760] printf("ip[%p]\n", ip); // IP [0x7ffEE904275c] // Cp = IP;printf("cp[%p] ip[%p]\n", cp, ip); Cp [0x7ffee904275c] IP [0x7ffee904275c] true if (cp == IP) {       printf("true\n");
    } else {        printf("false\n"); }}Copy the code

Pointers of both int and char are referred to as pointer types.

The constraint that Pointers point to object types is very weak for Pointers themselves, because in normal C, different types of Pointers are defined just for the convenience of calling. For example, if a pointer points to a structure, I can easily use the property field of that structure when I write code. Void * : void* : void* : void* : void* : void* : void* : void* So, in C, if you don’t use Pointers, you can think that the machine is helping us “take care of” memory.

However, if we use Pointers, since Pointers are very free, we can “manipulate” the memory ourselves.

03

A pointer commonly used in Go

In C language, pointer operation is completely unconstrained, which is very dangerous: the program ape in writing have to be careful, holding the pointer operation too much, pointing, pointing to the wrong place, it is not good ~

So the Go language was designed with this in mind by adding constraints to existing Pointers: data of pointer type is treated as a data type, and strict judgment is made at compile time.

For example: *int and *string are two different types, so *int and *string cannot be interoperable. Can you add and subtract? Of course not, because “number” is an integer, and *int or *string are other types than integers.

The Go language gives Pointers a “type” hat, all of a sudden the pointer limits dead.

And Go finally states that pointer types cannot be cast to each other. We know that int and string can be cast to each other. Pointers are addresses, and ints are cast to each other. The answer is no! Can *int and *string be cast? The answer is no, if can cast, the previous said to the pointer cover that “type” hat, is not in vain?

04

unsafe.Pointer

Well, after all that talk, I’m finally getting down to business. So what is the unsafe.Pointer? In fact, in a word: is the C language that awesome to the explosion of anything can point to the unsafe pointer. To be more precise: void*.

Unsafe.Pointer

Type ArbitraryType int // Indicates any type
                                Type Pointer *ArbitraryType // Represents a Pointer of any type
                                            Copy the code

The safe.pointer source note also provides four important rules for using safe.pointer:

Pointer type unsafe.Pointer Type unsafe.Pointer type unsafe.Pointer type unsafe.Pointer type unsafe.Pointer type unsafe.Pointer type unsafe.Pointer type unsafe.PointerUintptr this type can be converted to unsafe.pointer4, unsafe.Pointer can be converted to uintptrCopy the code

After reading the rules, you might ask: What is the Uintptr? Come on, there’s no better explanation than source code:

Note the location of the Uintptr, which is in the same package as int and uint. You can think of the Uintptr as “akin” to them, just a pointer only, but you can use it if you want.

For unsafe.Pointer, mostly used at compile time for Go; Since it can bypass the type system and access memory directly, it is relatively efficient to use, but the official attitude is not recommended because it is not secure. My personal advice is to use it if you can: the additional cost of efficiency is high.

Ok, let’s conclude with the pointer to Go: