Sometimes you may need to convert variables to other types. Golang does not allow arbitrary handling of such conversions, which are certain rules that are guaranteed by the type system's coercion. In this article, we will discuss what conversions are possible, what is not, and when to convert is valuable. Go is a strongly typed language. It is strict on the type, and the type error is reported during compilation. "' Gopackage mainimport" FMT "Func Main () {monster: = 1 +" 2 "FMT. Printf ("Monster:%v\n", Monster)} "" "> Go build# github.com/mlowicki/lab./lab.go:6: Cannot convert" 2 "to type int./ Lab.go:6: Invalid Operation:1 + "2" (Mismatched types int and string) ' JavaScript is one of the weakly typed languages, let's look at its actual effect: ' ' Javascriptva R monster = 1 + "foo" + function () {};console.info ("type:", typeof Monster) Console.info ("Value:", Monster); "' I will number, string, even letter Count together, it seems like a strange thing. But don't worry, JavaScript will handle these things for you with no error. ' Type:stringvalue:1foofunction () {} ' in a particular case, you might need to convert a variable to another type, such as passing it as a function argument or putting it in an expression. "' Gofunc f (text string) {Fmt. Println (text)}func main () {f (string (65))//integer constant is converted to a string. The expression called by the ' function ' is a common case of type conversion, and we see a similar transformation several times. The above code will work, but if you remove the type conversion: ' ' Gof (65) ' causes a compile-time error: "Cannot use of (type int) as type string in argument to F" (cannot make 65 of the integer type For the string type parameter give f) # # # underlying type (underlying type) string, Boolean, number, orThe underlying type of the literal type is still themselves, and in other cases the type declaration defines the underlying type: ' ' Gotype a string//StringType B A//StringType C Map[string]float64//Map[string]f Loat64 (type literal) type D C//Map[string]float64type E *d//*d "' (note is the corresponding underlying type) if the underlying type is the same, then the type conversion is hundred percent effective. "' Gopackage maintype a stringtype B atype C map[string]float64type C2 map[string]float64type D Cfunc Main () {var a a =" A "var B =" B "c: = Make (c) C2: = Do (C2) d: = Make (d) a = a (b) b = B (a) c = C (c2) c = C (d) var _ map[string]float64 = The program above Map[string]float64 (c)} "does not have any compilation problems. * * The definition of the underlying type cannot be recursive (definition of underlying types isn ' t recursive) * * * * The translator is skeptical that the definition of the underlying type cannot be recursive, according to **:>. > The definition of the underlying type is either interpreted into the built-in type (int, int64, float, string, bool ...) or recursively interpreted to the unnamed type. For example, > * b->a->string, String is a built-in type, explanation is stopped, the underlying type of B is string;> * U->t->map[s]float64, Map[s]float64 is unnamed Type, explanation stops, and U's underlying type is Map[s]float64. > ' > Type A string//string> type B A//string> type S string//string> type T map[s]float64//Map[s] Float64> type U T//map[s]float64> ' "' Gotype S stringtype t Map[s]float64....var _ Map[string]float64 = Make (t)" "The program above will error during compilation: ' ' Cannot use make (t) (type T) as type Map[string]float64 in assignment ' ' assignment error occurs because the underlying type of *t* is not ' map[string]float64 ' but ' m Ap[s]float64 '. The type conversion will also error: ' ' Govar _ Map[string]float64 = (Map[string]float64) ' (Make (t)) ' The code above will cause the following error at compile time: ' ' cannot convert make (t) ( Type T) to type Map[string]float64 ' # # assignable (assignability) Go Language Specification presents the concept of * assignable (assignability) *, which defines when a variable *v* can be assigned to *t * Variable of type. Let's understand one of its rules in code: When assigning a value, both should have the same underlying type, and at least one is not a named type. "' Gopackage mainimport" FMT "Func f (n [2]int) {fmt. PRINTLN (n)}type T [2]intfunc Main () {Var v T f (v)} ' program output "[0 0]". All type conversions are feasible within the scope of the assignable rules. The programmer can clearly express his specific idea in this way: "Gof ([2]int (v))" Above the calling method will be the same result as before. More information about the assignable properties can be found in [previous articles] (https://studygolang.com/articles/12381). The first rule of the > type conversion (with the same underlying type) and an assignable rule is coincident-when the underlying type is the same, at least one of the types is the Unnmaed type (the first example of this section). Weaker rules can affect more stringent rules. Therefore, when type conversions are only required to be consistent with the underlying type, it is not important whether the type is named/unnamed. # # Constant constant *v* can be converted to type *t*, when *v* can be represented by a variable of type *t*. "' Goa: = UInt32 (1<<32–1)//b: = UInt32 (1 <<)//constant 4294967296 overflows uint32c: = float32 (3.4e38)/ /d: = float32 (3.4e39)//constant 3.4e+39 overflows float32e: = String ("foo")//f: = UInt32 (1.1)//constant 1.1 truncated to Integerg: = BOOL (true)//h: = bool (1)//convert 1 (type int) to type Booli: = Rune (' ł ') J: = complex128 (0.0 + 1.0i) K: = String (65) "More in-depth descriptions of constants can be found in [official blogs] (https://blog.golang.org/constants). # # Number Type # # # floating point (floating-point numbers)-integer (integer) ' govar n float64 = 1.1var m int64 = Int64 (n) fmt. Println (M) "' fractional part is removed, so the code outputs" 1 ". For other transformations: * Floating-point number, float number, integer, Integer, * integer, floating-point number, plural-complex. The variable is rounded to the target precision: ' Govar a int64 = 2 << 60var b int32 = Int32 (a) fmt. Println (a)//2305843009213693952FMT. PRINTLN (b)//0a = 2 << 30b = Int32 (a) fmt. Println (a)//2147483648FMT. PRINTLN (b)// -2147483648b = 2 << 10a = Int64 (b) fmt. Println (a)//2048FMT. PRINTLN (b)//2048 ' # # pointer * Assignable (assignability) * handles pointer types in the same way as other types. ```Gopackage mainimport "FMT" type T *int64func main () {var n int64 = 1 var m int64 = 2 var p T = &n var q *int64 = & M p = q FMT. Println (*P)} ' program works and outputs ' 2 ', depending on the * assignable rules (assignability rule) that have been discussed. The underlying type of **int64* and *t* is the same, and **int64* is the unnamed type. Type conversions are more lenient. For the unnamed pointer type, the base type of the pointer has the same underlying type to convert. > Press: The base type of the pointer is the type of the variable that the pointer points to, such as P *int, and the base type of P is int. "' Gopackage mainimport" FMT "type T int64type u wtype W int64func Main () {var n T = 1 var m U = 2 var p *t = &n var q *u = &m p = (*t) (q) fmt. Println (*p)} "> **t* should be inside the brackets, otherwise he will be interpreted as * (T (q)) and the previous program, output" 2 ". Because *u* and *t* are the same base types as **u* and **t*, their underlying types are the same. The following assignment operation: ' GOP = Q ' is not successful because it tries to handle two different underlying types: **t* and **u*. As an exercise, let's change the statement a little bit to see what happens ' Gotype t *int64type U *wtype W int64func Main () {var n int64 = 1 var m W = 2 var p T = &n var Q U = &m p = T (q) fmt. Println (*p)} ' *u* and *w* 's declarations have been changed. Think about what's going to happen? The compiler reported an error in the following location "cannot convert Q (Type U) to type T" (Cannot convert Q (u) to type T): ' GOP = T (q) ' ' This is because the underlying type of *p* is **int64*, and *q* is **w*. The type of Q is named (*u*), so the rule that gets the underlying type of pointer base type does not apply here. # # # # integer String # # # # # # # # # # # # # # # # # # *n* to *string* built-in converts n into a UTF-8 encoded string that is composed of n-expressed characters. "' Gofmt. Printf ("%s\n", string (+)) fmt. Printf ("%s\n", String (322)) FMT. Printf ("%s\n", String (123456)) fmt. Printf ("%s\n", String (-1)) ' Output: ' Ał ' the first two transitions use a fully valid code bit. Perhaps you'll wonder why the latter two lines show strange symbols. It is a * replacement character (replacement character) *, which is a member of the *specials* Unicode section. Its code is \UFFFD ([More information] (Https://en.wikipedia.org/wiki/Specials_%28Unicode_block%29)) # # # Strings Brief Introduction strings is basically a slice of bytes: "' Gotext: =" abł "for I: = 0; I < Len (text); i++ {fmt. Println (Text[i])} ' output: ' 9798197130 ' 97 and 98 are UTF-8 encoded "a" and "B" characters. The output of the third and fourth lines is the UTF8 encoding of the character "ł", which occupies two bytes of space. The *range* loop helps iterate the code bits of the Unicode definition (code bits in Golang are called *rune*) ' gotext: = ' abł ' for _, S: = Range text {fmt. Printf ("%q% #v \ n", S, s)} ' output: ' ' A ', ' B ' 98 ' ł ' 322 ' ' > Want to learn more about the placeholders like *%q* and *%v*, you can see [FMT] (https://golang.org/pkg/f mt/) Package of documents more discussion can be found in ["Golang strings, Bytes, Rune and Characters"] (https://blog.golang.org/strings). After this quick explanation, between the string and the byte slicesConversion should no longer be difficult to understand. # # # String slice of bytes ' gobytes: = []byte ("Abł") Text: = string (bytes) fmt. Printf ("% #v \ n", bytes)//[]byte{0x61, 0x62, 0xc5, 0x82}fmt. Printf ("% #v \ n", text)//"abł" "slice consists of UTF8 encoded bytes of the converted string. # # # String slice of runes ' gorunes: = []rune ("Abł") fmt. Printf ("% #v \ n", runes)//[]int32{97, 98, 322}fmt. Printf ("%+q\n", runes)//[' a ' B ' \u0142 ']fmt. Printf ("% #v \ n", string (runes))//"abł", the slice created from the converted string is made up of Unicode encoded code bits (rune). # # End If you like this post, please follow [me] (HTTPS://MEDIUM.COM/GOLANGSPEC) so that you receive the latest article push message. # # information * [Golang Language Specification] (https://golang.org/ref/spec#Conversions) * [Go Strings, Bytes, runes and characters] (https://blog.golang.org /strings) * [Go's assignment] (https://studygolang.com/articles/12381) * [Go constants] (https://blog.golang.org/constants)
via:https://medium.com/golangspec/conversions-in-go-4301e8d84067
Author: Michałłowicki Translator: Magichan 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
211 Reads