The--string of Golang black Technology and []byte conversion

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

We know that Golang is a type-safe language relative to the C language. But the cost of security is the compromise of performance.
Below we have a glimpse of the underlying data of the "secret"--string Golang don't want us to see through Golang's "Black Tech".
Through the reflect package, we can know that in Golang, string and slice are actually structs:

type  sliceheader  struct { Data  uintptr  len   int  cap  int }   type  stringheader  struct {data  uintptr  len  int }    

Where the data is a pointer to the actual data address, Len represents the length of the database.
But in the string and []byte conversion process, what did Golang quietly do for us to achieve the security goal?
In the Golang language specification, the string data is forbidden to modify, trying to get the string and slice data pointer address through &s[0], &b[0] can not be compiled.
Below, we will take a glimpse of the "secret" behind Golang through Golang's "black Technology".

//return gostring ' s buffer Slice (enable modify string)Func Stringbytes (Sstring) Bytes {return* (*bytes) (unsafe. Pointer (&s))}//convert B to string without copyFunc bytesstring (b []byte) String {return* (*string) (unsafe. Pointer (&b))}//returns &S[0], which is not allowed in goFunc Stringpointer (Sstring)unsafe. Pointer {p: = (*reflect. Stringheader) (unsafe. Pointer (&s))return unsafe. Pointer (P.data)}//returns &B[0], which is not allowed in goFunc Bytespointer (b []byte)unsafe. Pointer {p: = (*reflect. Sliceheader) (unsafe. Pointer (&B))return unsafe. Pointer (P.data)}

The magic of the above 4 functions is through unsafe. Pointer and Reflect.xxxheader take the first address of the data and implement a direct conversion of string and []byte (these operations are prohibited at the language level).
Let's test the underlying secrets of the language through these "black technologies":

Func testpointer (t *testing. T) {s: = []string{"","","Hello","Hello"Fmt. Sprintf (""), FMT. Sprintf (""), FMT. Sprintf ("Hello"), FMT. Sprintf ("Hello"),} FMT. Println ("String to bytes:") forI, V: = range S {b: =unsafe. Stringbytes (v) b2: = []byte(v)ifB.writeable () {b[0] =' x '} FMT. Printf ("%d\ts=%5s\tptr (v) =%-12v\tptr (stringbytes (v) =%-12v\tptr ([]byte (v) =%-12v\n" ), I, V,unsafe. Stringpointer (v), B.pointer (),unsafe. Bytespointer (B2)} B: = []byte{        []byte{},        []byte{' h ',' E ',' l ',' l ',' O '},} FMT. Println ("Bytes to string:") forI, V: = range B {s1: =unsafe. Bytesstring (v) s2: =string(v) fmt. Printf ("%d\ts=%5s\tptr (v) =%-12v\tptr (stringbytes (v) =%-12v\tptr (String (v) =%-12v\n", I, S1,unsafe. Bytespointer (v), S1. Pointer (),unsafe. Stringpointer (s2))}}ConstN =3000000Func Benchmark_normal (b *testing. B) { forI: =1; i < N; i++ {s: = FMT. Sprintf ("12345678901234567890123456789012345678901234567890"BB: = []byte(s) bb[0] =' x 's =string(BB) s = S}}func benchmark_direct (b *testing. B) { forI: =1; i < N; i++ {s: = FMT. Sprintf ("12345678901234567890123456789012345678901234567890") BB: =unsafe. Stringbytes (s) bb[0] =' x 's = s}}//test Result//string to bytes://0 s= ptr (v) =0x51bd70 ptr (stringbytes (v) =0x51bd70 ptr ([]byte (v) =0xc042021c58//1 s= ptr (v) =0x51bd70 ptr (stringbytes (v) =0x51bd70 ptr ([]byte (v) =0xc042021c58//2 S=hello ptr (v) =0x51c2fa ptr (stringbytes (v) =0x51c2fa ptr ([]byte (v) =0xc042021c58//3 S=hello ptr (v) =0x51c2fa ptr (stringbytes (v) =0x51c2fa ptr ([]byte (v) =0xc042021c58//4 s= ptr (v) =<nil> ptr (stringbytes (v) =<nil> ptr ([]byte (v) =0xc042021c58//5 s= ptr (v) =<nil> ptr (stringbytes (v) =<nil> ptr ([]byte (v) =0xc042021c58//6 S=xello ptr (v) =0xc0420444b5 ptr (stringbytes (v) =0xc0420444b5 ptr ([]byte (v) =0xc042021c58//7 S=xello ptr (v) =0xc0420444ba ptr (stringbytes (v) =0xc0420444ba ptr ([]byte (v) =0xc042021c58//bytes to string://0 s= ptr (v) =0x5c38b8 ptr (stringbytes (v) =0x5c38b8 ptr (String (v) =<nil>//1 S=hello ptr (v) =0xc0420445e0 ptr (stringbytes (v) =0xc0420445e0 ptr (String (v) =0xc042021c38//benchmark_normal-4 1000000000 0.87 ns/op//benchmark_direct-4 2000000000 0.24 ns/op

The conclusions are as follows:
1.string constants are assigned to read-only segments at compile time, the corresponding data addresses are not writable, and the same string constants are not stored repeatedly.
2.fmt. The sprintf generated string is allocated on the heap, and the corresponding data address can be modified.
3. Constant empty string with data address, dynamically generated string not set data address
4.Golang string and []byte conversion, which copies data to the heap, and returns data pointing to the copied data
5. Dynamically generated strings, even if the content is the same, the data is in different spaces
6. Only dynamically generated string, data can be modified by black technology
8.string and []byte by copy conversion, performance loss nearly 4 times times

I put the test code here, please refer to:
Https://github.com/vipally/gx/blob/master/unsafe/string_test.go

Resources:
[1] Go language black magic http://studygolang.com/articles/2909

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.