Understand the type of Go language

Source: Internet
Author: User
Understanding types (type) is very necessary when I write code in C + + +. If you don't understand the type, you'll get a lot of trouble compiling or running the code. Regardless of the language, the type involves all aspects of the programming syntax. Strengthening the understanding of types and pointers is critical to improving the level of programming. This article will mainly explain the type. Let's start by looking at these bytes of memory: FFE4 | FFE3 | FFE2 | FFE1---|---|---|---00000000 | 11001011 | 01100101 | 00001010 what is the value of the byte on the address FFE1? If you try to answer a result, it is wrong. Why? Because I haven't told you what this byte means. I haven't told you the type information yet. What if I say that the above bytes represent a number? You may answer 10, then you are wrong again. Why? Because when I say this is a number, you think I mean a decimal number. > * * Cardinality (number base):**>> all numbering systems (numbering system) need to have a base (base) to work. From the time you were born, people taught you to count by the base 10来. This may be because most of us have 10 fingers and 10 toes. In addition, it is natural to use radix 10来 for mathematical calculation. The >> base defines the number of symbols that the numbering system contains. Base 10 will have 10 different symbols that represent the infinite things we can measure. The numbering system for base 10 is 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Once we have exceeded 9, we need to increase the length of the number. For example, 10, 100, and 1000. >> in the computer field, we have been using the other two bases. The first is the cardinality 2 (or binary number), such as the represented bit. The second type is the base 16 (or hexadecimal number), for example, the address represented in. >> in the binary numbering system (radix 2), there are only two symbols, 0 and 1. >> in the hex number system (Radix 16), there are 16 symbols, namely 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. >> If there are some apples on the table, those apples can be represented by any numbering system. We can say there are:>>-10,010,001 apples (using 2 as cardinality) >-145 apples (using 10 as cardinality) > 91 apples (using 16 as cardinality) >> all answers are correct, given the correct base.>> Note that each numbering system represents the number of symbols that Apple needs. The larger the cardinality, the higher the efficiency of the numbering system. >> using 16 as the base for computer addresses, IP addresses, and color codes is valuable. >> take a look at the number of:>> with three bases that represent the color of the HTML ("white")-using 2 as the base: 1111 1111 1111 1111 1111 1111 (24 characters) >-using 10 as the base: 1677721 5 (10 characters) >-use 16 as Radix: FFFFFF (6 characters) >> which numbering system would you choose to represent the color? Now, if I tell you that the byte at address FFE1 represents a number with a base of 10, you answer 10, which is correct. The type provides two information that you and the compiler need to perform the exercises we have just experienced. 1. Amount of memory to view (in bytes) 2. These byte representations of the Go language provide the following basic numeric types:> * * unsigned integers **>> uint8, uint16, UInt32, uint64>> * * signed integers **>> int8, int16, Int32, Int64>> * * Real **>> float32, float64>> * * pre-declared integer **>> uint, int, uintptr These keywords provide all type information. ' Uint8 ' contains a number based on 10, represented by 1 bytes of storage. The value of ' uint8 ' is from 0 to 255. ' Int32 ' contains a number based on 10, represented by 4 bytes of storage. The value of ' int32 ' is from 2147483648 to 2147483647. Pre-declared integers are mapped based on the architecture of the code you are building. On a 64-bit operating system, ' int ' maps to ' int64 ', and on a 32-bit system it maps to ' int32 '. All content that is stored in memory resolves to a numeric type. In Go, the string is just a series of ' uint8 ' types and contains rules for associating these bytes and identifying the end position of the string. In Go, the pointer is the ' uintptr ' type. Similarly, the OS-based architecture will be mapped to ' uint32 ' or ' UInt64 '. Go creates a special type for the pointer. In the past, many C programmers were writingCode, it is assumed that the pointer value always conforms to ' unsigned int '. As time goes by, language and architecture are escalating, and ultimately this is no longer the right one. Because the address becomes larger than the pre-declared ' unsigned int ', a lot of the code goes wrong. struct types are only a combination of many types, and these types will eventually resolve to numeric types. "' Gotype Example struct{boolvalue bool intvalue int16 floatvalue float32} ' ' This struct represents a complex type. It represents 7 bytes and is represented by three different numbers. ' bool ' has 1 bytes, ' int16 ' has 2 bytes, while ' float32 ' has 4 bytes. However, the struct eventually allocates 8 bytes in memory. To minimize memory defragmentation, memory boundaries are aligned when memory is allocated. To determine the alignment boundaries (alignment boundary) that Go uses on the architecture, you can run ' unsafe. Alignof ' function. The alignment boundary of Go on the 64-bit Darwin platform is 8 bytes. So when Go determines the memory allocation of our struct, it fills the bytes to ensure that the memory that is eventually occupied is a multiple of 8. The compiler will decide where to add the fill. If you want to learn more about the alignment and padding of struct members, see the link below: http://www.geeksforgeeks.org/ structure-member-alignment-padding-and-data-packing/The following program shows the padding that Go inserts into memory for the ' Example ' struct type: ' ' Gopackage Mainimport ("FMT" "unsafe") type Example struct {boolvalue bool intvalue int16 floatvalue Float32}func Main () {Example: = &example{Boolvalue:true, intvalue:10, floatvalue:3.141592,} examplenext: = &example{boolvalue:true, IntVa Lue:10, floatvalue:3.141592,} alignmentboundary: = UNSafe. Alignof (example) Sizebool: = unsafe. Sizeof (example. Boolvalue) Offsetbool: = unsafe. Offsetof (example. Boolvalue) Sizeint: = unsafe. Sizeof (example. Intvalue) Offsetint: = unsafe. Offsetof (example. Intvalue) Sizefloat: = unsafe. Sizeof (example. Floatvalue) Offsetfloat: = unsafe. Offsetof (example. Floatvalue) Sizeboolnext: = unsafe. Sizeof (examplenext.boolvalue) Offsetboolnext: = unsafe. Offsetof (Examplenext.boolvalue) fmt. Printf ("Alignment Boundary:%d\n", Alignmentboundary) fmt. Printf ("Boolvalue = Size:%d Offset:%d Addr:%v\n", Sizebool, Offsetbool, &example. Boolvalue) fmt. Printf ("intvalue = Size:%d Offset:%d Addr:%v\n", Sizeint, Offsetint, &example. Intvalue) fmt. Printf ("Floatvalue = Size:%d Offset:%d Addr:%v\n", Sizefloat, Offsetfloat, &example. Floatvalue) fmt. Printf ("Next = Size:%d Offset:%d Addr:%v\n", Sizeboolnext, Offsetboolnext, &examplenext.boolvalue)} ' the output is as follows: ' ' Bashalignment boundary:8boolvalue = size:1 offset:0 addr:0x21015b018intvalue = Size:2 OFFSET:2 addr:0x21015b01afloatvalue = size:4 offset:4 addr:0x21015b01cnext = size:1 offset:0 addr:0x21015b020 "' The structure type of The alignment boundary is indeed 8 bytes. The ' size ' value indicates the memory used when a field is read and written. As expected, this value matches the type information of the field. The ' offset ' offset value indicates the starting position of the field, the byte ordinal in memory consumption. The ' Addr ' address value indicates where each field starts in memory footprint. As we can see, Go has a 1-byte padding between the ' boolvalue ' and ' intvalue ' fields. The difference between the offset value and the two address is 2 bytes. You can also see that the next memory allocation is allocated 4 bytes from the last field in the struct. We let the struct have only one ' bool ' field (1 bytes) to confirm the 8-byte alignment rule. "' Gopackage mainimport (" FMT "" unsafe ") type Example struct {boolvalue bool}func main () {Example: = &example{boolv Alue:true,} examplenext: = &example{boolvalue:true,} alignmentboundary: = unsafe. Alignof (example) Sizebool: = unsafe. Sizeof (example. Boolvalue) Offsetbool: = unsafe. Offsetof (example. Boolvalue) Sizeboolnext: = unsafe. Sizeof (examplenext.boolvalue) Offsetboolnext: = unsafe. Offsetof (Examplenext.boolvalue) fmt. Printf ("Alignment Boundary:%d\n", Alignmentboundary) fmt. Printf ("Boolvalue = Size:%d Offset:%d Addr:%v\n", Sizebool, Offsetbool, &example. Boolvalue) fmt. Printf ("Next = SIze:%d Offset:%d Addr:%v\n ", Sizeboolnext, Offsetboolnext, &examplenext.boolvalue)} ' whose output is as follows: ' ' Bashalignment Boundary:8boolvalue = size:1 offset:0 addr:0x21015b018next = size:1 offset:0 addr:0x21015b020 "' Subtract two addresses, you will see two types of struct There is a 8-byte gap between allocations. In addition, this time the memory allocation starts at the same address as the previous example. To maintain the alignment boundary, Go fills the struct with 7 bytes. Regardless of padding, the ' size ' value actually represents the amount of memory we can read and write for each field. We can only manipulate memory when we use a numeric type, which is done by the assignment operator (=). For convenience, Go creates a number of complex types that can support assignment operators. These types have strings, arrays, and slices. To view a complete list of these types, view this document: Http://golang.org/ref/spec#Types. These complex types actually abstract the underlying numeric types, which we can find in implementations of various complex types. In this case, these complex types can read memory directly as if they were numeric types. Go is a type-safe language. This means that the compiler will always force the assignment operator to remain similar on both sides of the type. This is important because it prevents us from mistakenly reading memory. Let's say we want to do the following. If you try to compile the code, you will get an error. "' Gotype Example struct{boolvalue bool intvalue int16 floatvalue float32}example: = &example{boolvalue:true, IntVa Lue:10, Floatvalue:3.141592,}var pointer *int32pointer = *int32 (&example. Intvalue) *pointer = 20 "I'm trying to get the memory address of the ' Intvalue ' field (2 bytes) and store it on a pointer of type ' int32 '. Next, I tried to write a 4-byte integer to the memory address with a pointer. If this pointer is available, then I violate the type rule of the ' intvalue ' field and break memory in this process. FfE8 | FFE7 | FFE6 | FFE5 | FFE4 | FFE3 | FFE2 | FFE1---|---|---|---|---|---|---|---0 | 0 | 0 | 3.14 | 0 | 10 | 0 | Truepointer |---| FFE3 | FFE8 | FFE7 | FFE6 | FFE5 | FFE4 | FFE3 | FFE2 | FFE1---|---|---|---|---|---|---|---0 | 0 | 0 | 0 | 0 | 20 | 0 | true** the pointer will write 20 in 4 bytes between FFE3 and FFE6, depending on the memory footprint above. The value of ' intvalue ' will change to 20 as expected, but the value of ' floatvalue ' is now equal to 0. Imagine writing these bytes beyond the structure's memory allocations and starting to break the memory of other areas of the application. The resulting error will be random, unpredictable * *. The **go compiler will always ensure that memory alignment and transformation are secure * *. * * In the following transformation example, the compiler will error * *: ' ' goackage mainimport ("FMT")//Create a new Typetype int32ext Int32func main () {//Cast the NUM BER ten to a value of type jill var jill int32ext = Assign The value of Jill to Jack//* * Cannot use Jill (type Int3 2EXT) as type int32 in Assignment * * var jack int32 = Jill//Assign The value of Jill to Jack by casting//* * The Compil ER is happy * * var jack int32 = Int32 (Jill) Fmt. Printf ("%d\n", Jack)} ' first, we create a new ' Int32ext ' type in the system and tell the compiler that the type represents a ' int32 '. Next, we create a new variable named ' Jill ' and assign it a value of 10. The compiler allows this assignment operation because the number type is on the right side of the assignment operator. The compiler knows that the assignment is anThe whole. Now, we're trying to create a second variable called ' Jack ', whose type is ' int32 ', and we'll assign ' Jill ' to ' Jack '. In this case, the compiler throws an error: "' Bashcannot use Jill (Type Int32ext) as type int32 in Assignment '" The compiler thinks ' Jill ' is of type ' int32ext ' and does not make the security of the assignment Any assumptions. Now that we are using casts, the compiler allows the assignment of values and prints out values as expected. When we perform the transformation, the compiler checks the security of the assignment. Here, the compiler determines that this is the same type of value and allows the assignment operation. For some readers, this seems very basic, but it is the cornerstone of any programming language. Even if the type is abstract and you are manipulating memory, you should know exactly what you are doing. With these basics, we can discuss pointers in Go and pass parameters to the function. As usual, I hope this article will help you understand some of the possible blind spots.

Via:https://www.ardanlabs.com/blog/2013/07/understanding-type-in-go.html

Author: William Kennedy Translator: Noluye proofreading: polaris1119

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

432 Reads

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.