Golang Basic Type Finishing

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


Always use the use of blurred, do not know the basic types of what, it seems to be repeatedly made several times.

Golang Basic Type Finishing

Basic types and the need to be aware of defining variables

For the basic type of introduction, feel this blog speak more thorough, basically are from the source of the angle to start analysis, oneself did not understand so deep degree, here followed by the article, pick some major part of the record.
In the go language, data types are classified as static and underlying types , and it is felt that the underlying type is the type of C that is used when the Golang is implemented, whereas a static type is simply a type defined for the go language itself. Specific information can be viewed $goroot/src/runtime/runtime.h can see the byte type in Golang, by typedef uint8 byte definition, so that the reflection is directly used in Golang

package mainimport ("fmt""reflect")func main() {var b byte = 'D'fmt.Println(reflect.TypeOf(b))}//output: uint8

Here, by reflection, is the unsigned integer type represented by the uint8,8 bit.

String

You can see that the struct of type string is



struct String
{
byte* str;
intgo len;
}


The character array stores the actual data, Len stores the length. You can see from the struct that the string variable is not dynamically incremented after it has been defined, because Len is already written in.

StrConv conversion between string and basic data types in Golang
The fmt.sprintf function can also convert interface types to string types
http://blog.csdn.net/siddontang/article/details/23541587
The comparison of types between strings is strings. Equal??

Slice

Slice in order to achieve dynamic growth, add an additional element cap, which represents the allocated element, which is equivalent to the total space, Len represents the actual length of the slice for the user to use. This and Java ArrayList feel a bit similar, is to allocate a space, then see the space is not enough, then dynamically expand, but the process of expansion is not visible to the user:



struct Slice
{
byte* array;
uintgo len;
uintgo cap;
}

Note that the first parameter of slice is a byte pointer, which in fact points to the corresponding position of the underlying array.
To add that, with regard to initialization, the make function can be used to initialize the slice, map, and channel objects, which use the structure that must be initialized, for example, for slice, if not initialized, each value is nil Obviously it's not going to work. For the difference between make and new, you can refer to this blog

The following is an example of slice and string conversions, which can be used to better understand the relationship between slice and string and the underlying array, and the way in which the slice is generated differs from the internal operation.

Package Mainimport ("FMT" "unsafe") Func main () {//example 1var slice []int32 = make ([]int32, 5, ten)//p is a pointer to the slice type///here is Simulate a slice type and then convert it to P: = (*struct {array uintptrlen intcap int}) (unsafe. Pointer (&slice))//para v would print the Go type//if the value is a struct,//the%+v variant would include the struct ' s Field Namesfmt. Printf ("output:%+v\n", p)//example 2//declares an array without explicitly specifying the length of the array but through special tags ...//tell the compiler to let the compiler go automatically to calculate the var array = [...] Int32{1, 2, 3, 4, 5}//array to intercept and convert to slice the value var sliceb = array[2:4]fmt is automatically assigned to Len and cap at this time.  Printf ("before modify:array=%+v, slice =%+v\n", array, SLICEB)//At this point the underlying array and array in slice are the same//at this point where slice[0] is actually pointing to the underlying array Element 3 is located sliceb[0] = 678fmt. Printf ("after modify:array=%+v, slice =%+v\n", array, SLICEB)//example 3//Note If you are using Append mode to generate a new slice//there will be no similar effect Because the new underlying array is allocated with the Append method array = [...] Int32{1, 2, 3, 4, 5}var slicec = ARRAY[1:3]SLICEC = Append (SLICEC, 6, 7, 8)//Can compare this results found that two times the output of the array is the same and not because of the slice modification of the AR Ray causes the FMT to be affected. Printf ("before modify:array=%+v, slice =%+v\n", array, SLICEB) slicec[0] = 123fmt. Printf ("after modify:array=%+v, slice =%+v\n", array, SLICEB)//Pay attention to slice generated from slice when the principle is similar to the direct use of Slicea=sliceb[para1:para 2] The syntax//use of the same underlying array if the Append method will redistribute the underlying array}/* output: output:&{array:8725963136 len:5 cap:10}before modify:array=[1 2 3 4 5], slice = [3 4]after modify:array=[1 2 678 4 5], slice = [678 4]before modify:array=[1 2 3 4 5], slice = [3 4]afte R modify:array=[1 2 3 4 5], slice = [3 4]*/

Map

The map type, the slice type, and the channel type are reference types , which means that the structure always holds a pointer and maintains a reference to the underlying structure. In contrast, an array type is a value type. For reference types, when they are used, they are initialized after they are declared, only in order to establish a connection to the underlying data structure. When using a dictionary, either declare + initialize directly or use make initialization after declaring.

//直接声明加赋值mb := map[int]string{1: "hello", 2: "go"}//直接声明并初始化m := make(map[string]int)

After that, you can use it directly.

Array

When the array is defined, it is defined by the [n] type and can be assigned at the time of definition, such as [3]strng{"a", "B", "C"} can also be used in [] ... tag so that the compiler automatically recognizes the length of the array and initializes it.

interface and type conversions

The implementation of the interface type is complex, and several key points about the interface are sorted out, in practice, the place where the assertion expression is always used is not very good. This post is fairly good for assertions. This article is also relatively good introduction.

The go language is compiled, and once this code is written:

Containerpid = FMT. Sprintf ("%d", containerpid)

Then is the containerpid to do some string operations, such as the concatenation of strings, at compile time will be reported as the following error:

Invalid operation: "TestString" + containerpid (mismatched types string and interface {})

The main reason is because go is not the kind of dynamic execution of the language, because it is to compile and execute, in the compiler's view, this contaierid is still not converted to Strig type (?? Unless you do not use a variable with the same name, a new variable name is used so that the compilation can pass.

(1) The conversion of the normal type to the interface type is implicit, and the type assertion is required for the interface type conversion to the normal type. Because interface{} contains 0 methods, any type implements the interface{} interface, which is why you can assign any type of value to a variable of type interface{}, including nil, which is an example of implicit conversions:

package mainimport ("fmt""reflect")func main() {var val interface{} = "hello"fmt.Println(reflect.TypeOf(val)) //output: stringfmt.Println(val)val = []byte{'a', 'b', 'c'}fmt.Println(reflect.TypeOf(val)) //output: stringfmt.Println(val)}

(2) in an explicit type conversion, one way is to use Comma-ok's assertion syntax, since Golang does not have a generic declaration in the way that Java does, so there are times when it is not possible to determine which interfaces the type actually implements, so you can take an assertion expression and note X. (T) Such assertion type conversion,x must be an interface type of variable , T is a corresponding actual type, such as the following program, generate an array of type interface{}, and then through the implicit conversion, you can put any type of variable, You can then use an assertion expression to detect the corresponding type.

package mainimport ("fmt")type Test []interface{}func main() {test := make(Test, 5)test[0] = "a"test[1] = 2test[2] = truetest[3] = []byte("test")for index, element := range test {if value, ok := element.(string); ok {fmt.Printf("test[%d] is type of string the value is %v\n", index, value)} else if value, ok := element.([]byte); ok {fmt.Printf("test[%d] is type of string the []byte is %v\n", index, value)}}}

(3) When using instances to implement interface, also pay attention to the difference between the value method and the pointer method. interface here, more or less can see some dynamic language design style, is the so-called "duck type", that is, not by explicit indication inherited from an interface or class, but by the current type implementation method of the property set to determine. Understanding is, feel more than the static type of the grid, in short, my interface is written in there, if you want to inherit me, use my method, you put these methods implemented on the line, do not require you to display the declaration, inherit the self, how to do. Some dynamic types of languages can be typed at runtime for syntax detection, and the go Language is detectable during compilation. For example, the following:

Package Mainimport ("FMT" "reflect" "sort") type sortable interface {Len () intless (i, J int) Boolswap (i, J int)}type Sortstri  NgA [3]stringtype sortstringb [3]stringfunc (self Sortstringa) len () int {return Len "self"}func (self Sortstringa) less (I,  j int) bool {return self[i] < Self[j]}func (self Sortstringa) Swap (i, J int) {Self[i], self[j] = self[j], Self[i]}func (Self Sortstringa) Sort () {sort. Sort (self)}func (self *sortstringb) len () int {return Len ' self '}func (self *sortstringb) less (i, J int) bool {return self[ I] < Self[j]}func (self *sortstringb) Swap (i, J int) {Self[i], self[j] = Self[j], self[i]}func (self *sortstringb) Sort () {//Call the Sort method in the sort package to pass in a parameter as long as it is an instance of a type that implements Sort.interface Sort.sort (self)}func main () {sa: = sortstringa{"2", "3", "1"} SB1: = &sortstringb{"2", "3", "1"}SB2: = sortstringb{"2", "3", "1"}fmt. Println (reflect. TypeOf (SA)) sorta, OK: = interface{} (SA). (sortable) Fmt. Println (reflect. TypeOf (sorta)) fmt. Println (OK)//output:truesa. Sort () fmt. Printf ("SortstringaAfter sort%v:\n ", sa) sort. Sort (SA) fmt. Printf ("Sortstringa after sort%v:\n", sa)//FMT in Golang's source bundle. Println (reflect. TypeOf (SB1)) sort. Sort (SB1) sorted: = sort. IsSorted (SB1) fmt. Printf ("SB1 (TYPE:SORTSTRINGB) after sort%v:, is sorted:%v \ n", *sb1, sorted) sb2. Sort () fmt. Printf ("SB2 (TYPE:SORTSTRINGB) after sort:%v\n", SB2)}/*output:main. Sortstringamain.sortstringatruesortstringa after sort [2 3 1]:sortstringa after sort [2 3 1]:* main. SORTSTRINGBSB1 (TYPE:SORTSTRINGB) after sort [1 2 3]:, was sorted:true SB2 (TYPE:SORTSTRINGB) after sort: [1 2 3]

Feel this piece of code can still explain some problems:

    • First, a sortstable interface is defined with three methods in this interface, the three methods are the same as those defined in the basic type Sort.interface in the sort package, followed by a value method and a pointer method to implement the three methods.

    • As you can see, when using the value method, the data of the SA in the original variable is not sorted because the method is called by means of passing. It also tests the assertion expression, through the COMMA-OK expression, the SA type can be converted to the sortable type, which embodies its dynamic, but the reflection output, but also shows the type of its own declaration when the main. Sortstringa, where the strong static type (type one but ok no longer changes), the two combine to make the go language safe and efficient while maintaining a strong static type, but also flexible and safe to convert between different compatible types. (This article tells some interface of the original rational content, is good) notice inside the typical interface+switch+ assertion uses the way.

    • Since the three methods in sortable are the same as the three methods defined in Sort.interface, SA SB is equivalent to implementing the Sort.interface method, which can invoke functions in the sort package directly. However, it is important to note that the first implementation of the Sortstringa itself is implemented in three ways, the latter is the SORTSTRINGB pointer implementation of three methods, so SORTSTRINGB pointer type implementation of sort. Interface call when passing the past if the pointer is not OK, or compile error. Like direct sort. Sort (SB2) will error

SortStringB does not implement sort.Interface (Len method has pointer receiver)

Reference Resources

Http://www.infoq.com/cn/articles/go-interface-talk

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.