Go Language Practical Notes (27) | Go unsafe Pointer

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public or website http://www.flysnow.org/, the first time to see follow-up notes. If you feel helpful, share it with your friends and thank you for your support.

The go language is designed to be a strong type of static language for ease of writing, high efficiency, and reduced complexity. A strong type means that once defined, its type cannot be changed, and static means that the type check is done before it is run.

For security reasons, the Go language allows two pointer types to be converted.

Pointer type conversions

We typically use a pointer *T type that represents a pointer to a type T variable. For security reasons, two different pointer types cannot be converted to one another, for example *int *float64 .

12345678
func Main ()ip:=&ivar fp *float64 = (*float64) (IP) fmt. PRINTLN (FP)}

The above code when we compile, will be prompted cannot convert ip (type *int) to type *float64 , that is, can not be forced to transform. So what if we still need to do the conversion? This requires us to use the unsafe package Pointer , let's see unsafe.Pointer what it is, and then how to convert it.

Pointer

unsafe.Pointeris a special kind of pointer, it can contain any type of address, a bit similar to the C language of the void* pointer, all-round.

12345678910
func Main ()ip:=&ivar fp *float64 = (*float643fmt. Println (i)}

In the example above, we can convert to *int *float64 , and we try to operate on the new *float64 , the print output i , the same address will be found to i be changed.

The above example does not have any practical meaning, but we show that with unsafe.Pointer this universal pointer, we can *T do any conversion between them.

123
type int type Pointer *arbitrarytype

Can see unsafe.Pointer is actually a *int , a general-purpose pointer.

Let's take a look at unsafe.Pointer the 4 rules.

    1. Any pointer can be converted tounsafe.Pointer
    2. unsafe.Pointercan be converted to any pointer
    3. uintptrcan be converted tounsafe.Pointer
    4. unsafe.Pointercan be converted touintptr

The first two rules we have just demonstrated, mainly for *T1 and *T2 between the conversion, then the last two rules is what to do? We all know that we can't calculate the offsets, and we can't calculate them, but we can switch the pointers to the cheap ones, so *T uintptr uintptr We can access the specific memory and read and write to different memory.

Let's demonstrate the use of a field in the struct structure by modifying the pointer offset uintptr .

1234567891011121314151617
func Main ()  {u:=new(user) fmt. Println (*u) pname:= (*string) (unsafe. Pointer (U)) *pname="Zhang San"page:= (*int) (unsafe. Pointer (uintptrfmt. Println (*u)}typestructstringint}

Above, we use the memory offset to navigate to the fields we need to manipulate, and then change their values.

The first user time the name value is modified, because name it is the first field, so there is no offset, we get user the pointer, and then by moving unsafe.Pointer *string to the assignment operation.

The second modified user age value, because age it is not the first field, so we need a memory offset, the memory offset involves the calculation can only pass uintptr , we have to put user the pointer address to the first uintptr , and then we pass unsafe.Offsetof(u.age) Gets the value that needs to be offset, and the address operation (+) offset.

Now after the offset, the address is already user the age field, if you want to assign it, we need to turn to uintptr *int be able. So we can do it by turning uintptr unsafe.Pointer it into a switch *int .

Here we can see that the second offset of our expression is very long, but also do not fragment them, not as follows.

123
temp:=uintptr(unsafe. Pointer (U)) +unsafe. Offsetof (u.age) page:= (*int

Logically, the above code will not have any problem, but this will involve the GC, if we have these temporary variables are GC, then the resulting memory operation is wrong, we finally operate, do not know which block of memory, will cause inexplicable problems.

Summary

Unsafe is unsafe, so we should use it as sparingly as possible, such as the manipulation of memory, which bypasses the security of the go itself, and improper operation, which can destroy a piece of memory, and this problem is very difficult to locate.

Of course we can use it, such as conversions between arrays of the same underlying type, such as when using some of the functions in the Sync/atomic package, or when accessing a private field of a struct;

Also, the entire unsafe package is for the go compiler, not run, when we compile, the go compiler has processed them all.

"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public or website http://www.flysnow.org/, the first time to see follow-up notes. If you feel helpful, share it with your friends and thank you for your support.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.