Constant expressions

We made it through all the conversion rules! Let’s change gear and talk about… Constant expressions Constant expressions may contain only constant operands and are evaluated at compile time. Or framed differently: Any expression that contains non-constant operands, is not a constant expression. If you have a constant expression (e.g. 1 + 2) then extend it with a non-constant operand (e.g. 1 + 2 + userCount()), then it is no longer a constant expression.


Conversions from slice to array or array pointer

Conversions from slice to array or array pointer … Converting a slice to an array yields an array containing the elements of the underlying array of the slice. Similarly, converting a slice to an array pointer yields a pointer to the underlying array of the slice. In both cases, if the length of the slice is less than the length of the array, a run-time panic occurs. s := make([]byte, 2, 4) a0 := [0]byte(s) a1 := [1]byte(s[1:]) // a1[0] == s[1] a2 := [2]byte(s) // a2[0] == s[0] a4 := [4]byte(s) // panics: len([4]byte) > len(s) s0 := (*[0]byte)(s) // s0 !


Converting integers to strings

Sorry I missed yesterday. The family road trip ended later than expected, and I was too shot to write anything. Conversions to and from a string type … Finally, for historical reasons, an integer value may be converted to a string type. This form of conversion yields a string containing the (possibly multi-byte) UTF-8 representation of the Unicode code point with the given integer value. Values outside the range of valid Unicode code points are converted to "\uFFFD".


Converting slices to byte or rune slices

No livestream today, as I’m traveling with my family. See you next week! Conversions to and from a string type … Converting a value of a string type to a slice of bytes type yields a non-nil slice whose successive elements are the bytes of the string. []byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'} []byte("") // []byte{} bytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'} []myByte("world!") // []myByte{'w', 'o', 'r', 'l', 'd', '!

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.


Converting rune slices to strings

Yesterday we started through the list of rules and special cases for converting to and from string types. Let’s continue… Conversions to and from a string type … Converting a slice of runes to a string type yields a string that is the concatenation of the individual rune values converted to strings. string([]rune{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔" string([]rune{}) // "" string([]rune(nil)) // "" type runes []rune string(runes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔" type myRune rune string([]myRune{0x266b, 0x266c}) // "\u266b\u266c" == "♫♬" myString([]myRune{0x1f30e}) // "\U0001f30e" == "🌎" I think this one is pretty intuitive.


Conversions to and from a string type

Before I dive in to today’s spec discussion… are you enjoying this series? If so, would you do me a favor and help spread the word? Can you share a link to this message with a fellow Gopher, or on your work chat? Conversion to and from string types is a minefield of special cases in Go. So this will take at least a couple of days. Let’s dive in.


Conversions between numeric types

So we’ve gone through the high-level conversion stuff… now we dive into some particulars. Today, numeric conversions. Conversions between numeric types For the conversion of non-constant numeric values, the following rules apply: When converting between integer types, if the value is a signed integer, it is sign extended to implicit infinite precision; otherwise it is zero extended. It is then truncated to fit in the result type’s size. For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0.


Type Conversion & struct tgs

We’ve already mentioned that struct tags are ignored when doing conversion between struct types. Now we see where that’s defined, along with an example: Conversions … Struct tags are ignored when comparing struct types for identity for the purpose of conversion: type Person struct { Name string Address *struct { Street string City string } } var data *struct { Name string `json:"name"` Address *struct { Street string `json:"street"` City string `json:"city"` } `json:"address"` } var person = (*Person)(data) // ignoring tags, the underlying types are identical I don’t think there’s much else to say about that, so let’s move on, and finish up this section.


Conversion of type parameters

Today I’ll be live-streaming again, doing TDD on an open-source project. I hope you can join! Conversions … Additionally, if T or x’s type V are type parameters, x can also be converted to type T if one of the following conditions applies: Both V and T are type parameters and a value of each type in V’s type set can be converted to each type in T’s type set. Only V is a type parameter and a value of each type in V’s type set can be converted to T.


Non-constant conversions, part 2

Today we’ll finish the list of non-constant conversion rules that don’t relate to type parameters. Conversions … x’s type and T are both integer or floating point types. x’s type and T are both complex types. x is an integer or a slice of bytes or runes and T is a string type. x is a string and T is a slice of bytes or runes. x is a slice, T is an array [Go 1.


Non-constant conversions

Yesterday we looked at conversions of constants. Let’s now consider the more common conversion scenarios of variables and other non-constant expressions. Conversions … A non-constant value x can be converted to type T in any of these cases: x is assignable to T. ignoring struct tags (see below), x’s type and T are not type parameters but have identical underlying types. ignoring struct tags (see below), x’s type and T are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.