This is a creation in Article, where the information may have evolved or changed.
Golang variables in the form of memory
The int uint differs from the compiler in different systems, and theGC ,GCCGO is implemented in 64-bit systems, the int uint is 64 bits, and the 32-bit system is 32-bit.
Similarly, the pointer length in the 64-bit system is 8 bytes, and the 32-bit system is 4 bytes.
An array, a structure in which data is tightly connected in memory.
String
typestringStructstruct{ strunsafe.Pointer lenint}
The string is represented by a 16-byte data structure that contains a pointer to the string to store the data and a length data. The use of string slices to generate new strings does not involve memory allocation and copying operations, because multiple strings reuse the underlying storage data because the strings are immutable (changing the string generates a new string) and there is no memory sharing problem.
Go uses utf-8 encoded string, (Utf-8 encoding author is one of Go authors), go string each character is Rune,rune is UInt32 alias, Unicode character length may be 1,2,3,4 bytes. If the statistic count is rune.
s:="刘曦光"len(s) // 9,字节数len([]rune(s)) // 3,rune 数
Use the subscript to access the string, not the nth character, but the nth byte of the underlying storage.
s:="刘曦光"s[0] // 229
A problem that has not been clear:the relationship between Unicode UTF-8 string
In the ancient era of programmers may appear character sets, encoding methods and other issues, but now we develop coding methods and other issues generally have an editor or the IDE provides perfect support.
By reading the following two articles I have figured out the relationship between them:
- Character-coded notes: Ascii,unicode and UTF-8
- The Absolute Minimum every software Developer absolutely, positively must Know about Unicode and Character sets (No excuse s!)
Nutshell:
- Unicode is the charset character set and for-see corresponds to code points/yards/code point
- The UTF-8 is encoding encoded, the for store is stored on the storage device, and the memory is external memory
The Unicode character set can represent all characters, but it has different implementations, such as utf-18,utf-16 and so on. Yes, UTF-8 is just one way to implement Unicode. UTF-8 uses a special encoding method, the shorter the number of bytes that correspond to the characters with high frequency.
Error examples
In the course of learning Java, I read some of the wrong information that Java uses Unicode encoding, each character is stored in two bytes, and all characters can be expressed.
In fact, a total of two bytes 16 bits can be expressed in the number of characters is 2 * * = 65536, is not enough to express all the characters, and Unicode is only a character set rather than encoding method. There is no real limit to the number of Unicode encodings, in fact they have far more than 65,536, so not all Unicode encodings can be compressed to 2 bytes.
Even though the Times New Roman uses different styles to display a, a is still the same character. Just use different font styles to display, store or use the same encoding method.
In different systems may have big-endian storage Big-endian or small-end storage Small-endian, more on this aspect can read Nanyi an article: Understanding byte-order
In Go a string was in effect a read-only slice of bytes.
unsafe.Sizeof(variable)
hexadecimal represents a string
s:="\x68\x65\x6c\x6c\x6f"// "hello"
Use 0xFF for 16 in numbers, 0111 for octal
fmt.Printf("%q",string(100))
The output is "D", not "100"
Go source code only allows the use of UTF-8 encoding
Do not escape \ n, \xff , etc. using raw string
s:=`hello world`
Can the string in Go contain only UTF-8 encoding?
No, string can also control each byte in the form of "\xff".
For range iterates through every character in a string, not bytes
s := "Hello World" for _, v := Range s {the type of//V is int32, i.e. Rune FMT.Println("%v", v)}FMT.Println() for _, v := Range s { FMT.Printf("%v", string(v))}
Output
10410110810811132 119111114108100h e l l o w o r l d
There are many UTF-8 support in the official library Unicode/utf8
The disadvantage of a string referencing the same source string: The source string cannot be reclaimed for a large source string, even if only a small part is referenced.
The benefit of strings referencing the same source string: The cut and copy operations of the strings are expensive and need to be divided into two steps, allocation and replication.
Golang official description of strings
Slice
typeslicestruct{ arrayunsafe.Pointer len int cap int}
arrays, slice do not actually replicate a single piece of data, but instead reuse the underlying array storage
Even if the slice is assigned, the underlying array is used in the same one, and one of the changes will trigger another synchronization change.
func Main() {x := []int{1, 2, 3, 4, 5}y := x y[0] = Ten FMT.Println("x:", x) FMT.Println("y:", y)}
Output
x: [10 2 3 4 5]y: [10 2 3 4 5]
Expansion
Operations such as append on slice may trigger slice expansion
Expansion rules:
- If the current CAP < 1024, increase by twice times per time, otherwise each time you increase by 1/4 of the current cap
Create slice
You can create a slice,new with new or make to return an already zeroed pointer, and make returns a complex structure.
Creating slice is best created with make
For more information, please refer to: In-depth analysis Go Slice Bottom implementation
Map
type Hmap struct { Count int //# Live cells = = size of map. Must is first (used by Len () builtin) Flags uint8 B uint8 //Log_2 of # of buckets (can hold up to Loadfactor * 2^b items) Noverflow uint16 //Approximate number of overflow buckets; see Incrnoverflow for details Hash0 UInt32 //Hash seed Buckets unsafe.Pointer //array of 2^b Buckets. May is nil if count==0. oldbuckets unsafe.Pointer //Previous bucket array of half the size, Non-nil only when growing nevacuate UIntPtr //Progress counter for evacuation (buckets less than this has been evacuated) Extra *Mapextra //Optional fields}
func Main() {M1 := Make(Map[int]int)m2 := M1 for I := 0; I < +; I++ { M1[I] = I } for k, _ := Range M1 {_, OK := m2[k] FMT.Println(OK) }}
Always output true.
The replication of map does not reallocate space, but instead uses the underlying storage structure, even if the M1 inserts a lot of data, has triggered the extension, buckets redistribution, M1 and M2 will still change synchronously.
Map uses the list to solve the hash conflict, not the open address, because the open address method degrades quickly when it is actually expanding. The location of the list does not require a recalculation of the hash value because the expansion is multiplied.
Map expansion using two bucket method, not one-time to complete the expansion operation, and not time to move the elements in the oldbuckets into buckets, although this can not eliminate the total expansion time, but the expansion time is allocated to each insert, so as to prevent the program from a long time blocking.
For more information, please refer to:
- How do I design and implement a thread-safe Map? (Previous article)
- How do I design and implement a thread-safe Map? (Next article)