Go FAQ 101

(This is an unofficial Go FAQ. The official one is here.)

Index:

What does the compile error message non-name *** on left side of := mean?

Up to now (Go 1.10), there is a mandatory rule for short variable declarations:
All items at the left side of := must be pure identifiers and at least one of them must be a new variable name.
This means container elements (x[i]), struct fields (x.f), pointer dereferences and qualified identifiers can't appear at the left side of :=.

Currently, there is an open issue (which was merged with a more related one) for this problem. It looks Go authors want to leave this problem unresolved until Go 2.0.

What does the compile error message unexpected newline, expecting { ... mean?

In Go, we can't break a code line at an arbitrary position. Please read line break rules in Go for details. By the rules, generally, it is not okay to break code lines just before the open brackets.

For example, the following code
if true
{
}

for i := 0; i < 10; i++
{
}

var _ = []int
{
	1, 2, 3
}
will be interpreted as
if true;
{
}

for i := 0; i < 10; i++;
{
}

var _ = []int;
{
	1, 2, 3;
}
Go compilers will report an error for each open bracket {. To avoid these errors, we should rewrite the above code as the following.
if true {
}

for i := 0; i < 10; i++ {
}

var _ = []int {
	1, 2, 3,
}

What does the compiler error message declared and not used mean?

For the standard Go compiler, each variable declared in local code blocks must be used as a RHS value (right-hand side) for at lease once.

So the following code fails to compile.
func f(x bool) {
	var y = 1 // y declared and not used
	if x {
		y = 2
	}
}

Does Go runtime maintain the iteration orders for maps?

No. Go 1 specification says the iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. For the standard Go compiler, the map iteration orders are some randomized. If you require a stable iteration order for a map you must maintain the order by yourself. Please read Go maps in action for more information.

Will Go compilers do padding to ensure field alignments for struct types?

At least for the standard Go compiler and gccgo, the answer is yes. Padding is OS and compiler dependent.

Example:
type T1 struct {
	a int8
	// 7 bytes padded on AMD64 OS and pad 3 bytes padded on i386 OS here
	b int64
	c int16
	// 6 bytes padded on AMD64 OS and pad 2 bytes padded on i386 OS here
}

type T2 struct {
	a int8
	// 1 byte padded on both AMD64 and i386 OS here
	c int16
	// 4 bytes padded on AMD64 OS here. No padding on i386 OS
	b int64
}

The addresses of T1.b values in memory must be 8-byte aligned on AMD64 OS and 4-byte aligned on i386 OS, this is why there will be 7 bytes padded on AMD64 OS and 3 bytes padded on i386 OS after T1.a.

Go specification makes some guarantees for type alignments. One of them is the alignment of a struct type is its largest alignment of its field types. So T1 is also 8-byte aligned on AMD64 OS and 4-byte aligned on i386 (same as type of T1.b, int64), and the standard Go compiler will ensure the size of values of a type is a multiple of the alignment guarantee of the type, this is why there will be 6 bytes padded on AMD64 OS and 2 bytes padded on i386 OS at the end of T1 values.

The orders of the fields in a struct will affect padding, and padding will affect the size of the struct afterwards. On AMD64 OS, the size of T1 values is 24, but the size of T2 values is 16.

Go Compilers will not rearrange struct fields to minimize struct value sizes. Doing this may cause some unexpected results. However, programmers can minimize padding by reordering the fields manually.

Why does the final field of a zero-sized type in a struct contribute to the size of the struct sometimes?

(This is not a Go spec rule. It is a compiler specified implementation. Here is the compiler is the standard Go compiler. Please view issue#9401 for details.)

In the current standard Go runtime implementation, if a memory block is referenced by at least one active pointer, then the memory block will not be viewed as garbage and will not be collected. All the fields of an addressable struct value can be taken addresses. If the size of the final field in a non-zero-sized struct is zero, then taking the address of the final field in the struct value will return an address which beyonds the allocated memory block for the struct value. The returned address may

To avoid the problems, the Go standard compiler will ensure that taking the address of the final field in a non-zero-sized struct will never return an address which beyonds the allocated memory block for the struct. The Go standard compiler implements this by padding some bytes before the final zero-sized field when needed.

If the types of all fields in a struct type are zero-sized (so the struct is also a zero-sized type), then there is no need to pad bytes in the struct, for the Go standard compiler treats zero-sized types specially.

Example:
package main

import (
	"unsafe"
	"fmt"
)

func main() {
	type T1 struct {
		a struct{}
		x int64
	}
	fmt.Println(unsafe.Sizeof(T1{})) // 8
	
	type T2 struct {
		x int64
		a struct{}
	}
	fmt.Println(unsafe.Sizeof(T2{})) // 16
}

Is new(T) a sugar of var t T; (&t)?

Generally you can think so. The memory block allocated by new may be either on stack or on heap. There would some subtle differences between the two, depending on compiler implementations.

What does the runtime error message all goroutines are asleep - deadlock mean?

The word asleep is not accurate here, it means in blocking state in fact. As a blocking goroutine can only be unblocked by another goroutine, if all goroutines in a program enter blocking state, then all of they will stay in blocking state for ever. This means the program is deadlocked. A normal running program is never expected to be deadlocked, so the standard Go runtime makes the program crash and exit.

Are 64-bit variables and struct fields guaranteed to be 64-bit aligned so that they can be accessed atomically?

The addresses passed to the 64-bit functions in sync/atomic package must be 64-bit aligned, otherwise, calls to these functions may panic at run time.

For Go programs run on 64-bit OSes, 64-bit values are guaranteed to be 64-bit aligned. So they can be accessed atomically.

For Go programs run on 32-bit OSes, there is no the universal guarantee. But following 64-bit words are guaranteed to be able to be accessed atomically:

Here, an allocated value means the address of the value is the start address of the memory block the value locates at. In other words, the value is placed at the beginning of the memory block it locates at.

A qualified Go compiler should promise that all elements in an array/slice can also be accessed atomically if one element in the array/slice can be accessed atomically and the element type is a 64-bit word type, though the official documentation doesn't make this guarantee.

Example:
package main

import (
	"sync/atomic"
)

type T struct {
	a uint64
	b bool
	c int64
}

type V struct {
	d byte
	t T // t.a is not the first field in V.
}

var x int64
var y [3]uint64
var z = make([]int64, 5)
var t T

var v V

func main() {
	var x2 int64
	var y2 [3]uint64
	var z2 = make([]int64, 5)
	var t2 T
	
	var v2 = new(V)
	
	// following lines are guaranteed to be safe on
	// both 64-bit and 32-bit OS.
	atomic.LoadInt64(&x)
	atomic.LoadUint64(&y[1])
	atomic.LoadInt64(&z[2])
	atomic.LoadUint64(&t.a)
	
	atomic.LoadInt64(&x2)
	atomic.LoadUint64(&y2[1])
	atomic.LoadInt64(&z2[2])
	atomic.LoadUint64(&t2.a)
	
	// the following two lines are safe on 64-bit OS
	// but may be panic on 32-bit OS	
	atomic.LoadUint64(&v.t.a)
	atomic.LoadUint64(&v2.t.a)
}

Are assignments of values atomic operations?

No for the standard Go compiler, even if the sizes of the assigned values are one word.

Pleae view the official question for more details.

Is every zero value composed of a sequence of zero bytes in memory?

For most types, this is true. In fact, this is compiler dependent. For example, for the standard Go runtime, the statement is wrong for some zero values of string types.

Evidence:
package main

import (
	"unsafe"
	"fmt"
)

func main() {
	var s1 string
	fmt.Println(s1 == "") // true
	fmt.Println(*(*uintptr)(unsafe.Pointer(&s1))) // 0
	var s2 = "abc"[0:0]
	fmt.Println(s2 == "") // true
	fmt.Println(*(*uintptr)(unsafe.Pointer(&s2))) // 4869856
	fmt.Println(s1 == s2) // true
}

Inversely, for all the processors/architectures the standard Go compiler currently supports, if all bytes in a value are zero, then the value must be a zero value of its type. However, Go specification doesn't guarantee this. I have heard that on some very old processors, nil pointers are not zero in memory.

Does the standard Go compiler support function inline?

Yes, the standard Go compiler supports function inline. The compiler will inline short leaf functions, automatically. Leaf functions are the functions which doesn't contain function calls. The specific inline rules may change from version to version.

Currently (Go 1.10), for the standard Go compiler,

How to manipulate pointer values atomically?

Example:
import (
	"unsafe"
	"sync/atomic"
)

type T int // just a demo

var p *T

func demo(newP *T) {
	// load
	var _ = (*T)(atomic.LoadPointer(
		(*unsafe.Pointer)(unsafe.Pointer(&p)),
		))
	
	// store
	atomic.StorePointer(
		(*unsafe.Pointer)(unsafe.Pointer(&p)),
		unsafe.Pointer(newP),
		)
	
	
	// swap
	var oldP = (*T)(atomic.SwapPointer(
		(*unsafe.Pointer)(unsafe.Pointer(&p)),
		unsafe.Pointer(newP),
		))
	
	// compare and swap
	var swapped = atomic.CompareAndSwapPointer(
		(*unsafe.Pointer)(unsafe.Pointer(&p)),
		unsafe.Pointer(oldP),
		unsafe.Pointer(newP),
		)
	
	_ = swapped
}
Yes, now it is much verbose to use the pointer atomic functions.

How to get the number of days of any month by using as few code lines as possible?

Assume the input year is a nature year and the input month is also a nature month (January is 1).
days := time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC).Day()
For Go time APIs, the usual month range is [1, 12] and the start day of each month is 1. The start time of a month m in year y is time.Date(y, m, 1, 0, 0, 0, 0, time.UTC).

The arguments passed to time.Date can be outside their usual ranges and will be normalized during the conversion. For example, January 32 will be converted to February 1.

Here are some date usage examples in Go:
package main

import (
	"time"
	"fmt"
)

func main() {
	// 2017-02-01 00:00:00 +0000 UTC
	fmt.Println(time.Date(2017, 1, 32, 0, 0, 0, 0, time.UTC))
	
	// 2017-01-31 23:59:59.999999999 +0000 UTC
	fmt.Println(time.Date(2017, 1, 32, 0, 0, 0, -1, time.UTC))
	
	// 2017-01-31 00:00:00 +0000 UTC
	fmt.Println(time.Date(2017, 2, 0, 0, 0, 0, 0, time.UTC))
	
	// 2016-12-31 00:00:00 +0000 UTC
	fmt.Println(time.Date(2016, 13, 0, 0, 0, 0, 0, time.UTC))
	
	// 2017-02-01 00:00:00 +0000 UTC
	fmt.Println(time.Date(2016, 13, 32, 0, 0, 0, 0, time.UTC))
}

What is the difference between the function call time.Sleep(d) and the channel receive operation <-time.After(d)?

Thw two will both pause the currrent goroutine execution for a certain duration. The difference is the function call time.Sleep(d) will let the current goroutine enter sleeping status (not a goroutine state), but still stay in running state, whereas, the channel receive operation <-time.After(d) will let the current goroutine enter blocking state.

Can I use finalizers as object destructors?

In Go programs, we can set a finalizer function for an object by using the runtime.SetFinalizer function. The finalizer function will be called before the object is garbage collected. But finalizers are never intended to be used as destructors of objects. The finalizers set by runtime.SetFinalizer are not guaranteed to run. So you shouldn't rely on finalizers for your program correctness.

The main intention of finalizers is for libraries maintainers to make extra efforts to remedy the damage caused by libraries users don't use the libraries correctly. For example, in a program, if we use the os.Open to open many files but forget to close them after using them, then the program will hold many file descriptors until the program exits. This is resource leak. To avoid the program holding too many file descriptors, the maintainers of the os package will set a finalizer on the every created os.File object. The finalizer will close the file descriptor stored in the os.File object. As above mentioned, the finalizers are not guaranteed to be called. They are just used to make the extent of resource leak as small as possible.

Sometimes, to avoid a finalizer of an object being called too early, we can use the runtime.KeepAlive function to prevent the object from being garbage collected too early.

Please note, some finalizers will never be called for sure, and sometimes setting finalizers improperly will prevent some objects from being garbage collected. Please read the runtime.SetFinalizer function documentation to get more details.

Calls of the TrimLeft and TrimRight functions in the strings and bytes standard packages often return unexpected results, are there bugs in these function implementations?

Aha, maybe there are bugs in the implementations, but none are confirmed now. If the return results are unexpected, it is more possible that your expectations are not correct.

There are many trim functions in strings and bytes standard packages. These functions can be categorized into two groups:
  1. Trim, TrimLeft, TrimRight, TrimSpace, TrimFunc, TrimLeftFunc, TrimRightFunc. These functions will trim all leading or trailing UTF-8-encoded Unicode code points (a.k.a. runes) which satisfy the specified or implied conditions (TrimSpace implies to trim all kinds of white spaces). Each of the leading or trailing runes will be checked until one doesn't satisfy the specified or implied conditions.
  2. TrimPrefix, TrimSuffix. The two functions will trim the specified prefix or suffix substrings (or subslices) as a whole.

Some programmers misuse the TrimLeft and TrimRight functions as TrimPrefix and TrimSuffix functions when they use the trim functions the first time. Certainly, the return results are very possible not the expecteds.

Example:
package main

import (
	"fmt"
	"strings"
)

func main() {
	var s = "abaay森z众xbbab"
	fmt.Println(strings.TrimPrefix(s, "ab")) // aay森z众xbbab
	fmt.Println(strings.TrimSuffix(s, "ab")) // abaay森z众xbb
	fmt.Println(strings.TrimLeft(s, "ab"))   // y森z众xbbab
	fmt.Println(strings.TrimRight(s, "ab"))  // abaay森z众x
	fmt.Println(strings.Trim(s, "ab"))       // y森z众x
	fmt.Println(strings.TrimFunc(s, func(r rune) bool {
			return r < 128 // trim all ascii chars
		},
	)) // 森z众
}

Are fmt.Print, fmt.Println and fmt.Printf functions synchronized?

No, these functions are not synchronized. Please use the corresponding functions in the log standard package instead when synchronizations are neededed. You can call log.SetFlags(0) to remove the prefix from each log line.

What are the differences between the fmt.Print and fmt.Println functions?

The fmt.Println function will always write a space between two adjacent arguments, whereas the fmt.Print function will write a space between two adjacent arguments only if both of (the concrete values of) the two adjacent arguments are not strings.

Another difference is fmt.Println will write a newline character in the end, but the fmt.Print function will not.

Is there any difference between the log.Print and log.Println functions?

The difference between the log.Print and log.Println functions is the sams as the first difference between the fmt.Print and fmt.Println functions described in the last question.

Both of the two functions will write a newline character in the end.

What are the differences between the built-in print/println functions and the corresponding print functions in the fmt and log standard packages?

There are several differences between the two sets of functions.
  1. The built-in print/println functions will write to the standard error. The print functions in the fmt standard package will write to the standard output. The print functions in the log standard package will write to the standard error by default, whereas which can be configured through the log.SetOutput function.
  2. The built-in println function never writes spaces between arguments.
  3. The built-in print/println functions can't take array and struct arguments.
  4. For an argument of a composite type, the built-in print/println functions write the addresses of the underlying value parts of the argument, whereas the print functions in the fmt and log standard packages try to write the value literal of the argument.
  5. Currently (Go 1.10), for the standard Go compiler, calls to the built-in print/println functions will not make the values referenced by the arguments of the calls escape to heap, whereas the print functions in the fmt and log standard packages will.
  6. If an argument has a String() string or Error() string method, the print functions in the fmt and log standard packages will try to call that method when writing the argument, whereas the built-in print/println functions will ignore methods of arguments.
  7. The built-in print/println functions are not guaranteed to exist in future Go versions.

What is the difference between the random numbers produced by the math/rand standard package and the crypto/rand standard package?

The pseudo random numbers produced by the math/rand standard package are determinstic for a given seed. The produced random numbers are not good for security-sensitive contexts. For cryptographical security purepose, we should use the pseudo random numbers produced by the crypto/rand standard package.

Why isn't there a math.Round function?

There is a math.Round function, but only since Go 1.10. Two new functions, math.Round and math.RoundToEven have been added since Go 1.10.

Before Go 1.10, there is a long time in disputing whether or not the math.Round function should be added to standard package or not. In the end, the proposal is adopted.

Which types don't support comparisons?

Following types don't support comparisons:

Types which don't support comparisons can't be used as the key type of map types.

Please note,

On why slice, map and function types don't support comparison, please read this answer in the official Go FAQ.

Why aren't two nil values equal sometimes?

(The answer in the official Go FAQ may also answer this question.)

Before answering this question, let's look some facts in Go: From these facts, we can get:

Please read interfaces in Go and nils in Go for detailed explanations.

For example:
package main

import "fmt"

func main() {
	var pi *int = nil
	var pb *bool = nil
	var x interface{} = pi
	var y interface{} = pb
	var z interface{} = nil
	
	fmt.Println(x == y)   // false
	fmt.Println(x == nil) // false
	fmt.Println(y == nil) // false
	fmt.Println(x == z)   // false
	fmt.Println(y == z)   // false
}

Why don't type []T1 and []T2 share the same underlying type even if the two different types T1 and T2 share the same underlying type?

(It looks the official Go FAQ also added a similar question not long ago.)

In Go, values of a slice type can be converted to another slice type without using the unsafe mechanisms only if the two slice types share the same underlying type (this article lists the full list of value conversion rules).

The underlying type of an unnamed composite type is the composite type itself. So even if two different types T1 and T2 share the same underlying type, type []T1 and []T2 are still different types, so their underlying types are also different, which means values of one of them can't be converted to the other.

The reasons for the underlying types of []T1 and []T2 are not same are:

The same reasons are also valid for other composite types. For example, type map[T]T1 and map[T]T2 also don't share the same underlying type even if T1 and T2 share the same underlying type.

It is possible that values of type []T1 can be converted to []T2 by using the unsafe mechanisms, but generally this is not recommended:
package main

import (
	"fmt"
	"unsafe"
)

func main() {
	type MyInt int
	
	var a = []int{7, 8, 9}
	var b = *(*[]MyInt)(unsafe.Pointer(&a))
	b[0]= 123
	fmt.Println(a) // [123 8 9]
	fmt.Println(b) // [123 8 9]
	fmt.Printf("%T \n", a) // []int
	fmt.Printf("%T \n", b) // []main.MyInt
}

Which values can and which values can't be taken addresses?

Following values can't be taken addresses:
Please note, there is a syntax sugar, &T{}, in Go. It is a short form of tmp := T{}; (&tmp). So &T{} is legal doesn't mean T{} is addressable.

Following values can be taken addresses:

Why are map elements unaddressable?

The first reason is that, in Go, for a map m and a key value k, the read operation m[k] is always valid, even if m is a nil map or m doesn't contain the key k. For the two circumstances, m[k] is always the zero value of the map element type. The zero value of any type should be immutable. Immutable values can't be taken addresses, otherwise their values may be modified. Whether or not m[k] is a zero value can only be detected at run time. So, to make it safe and consistent, Go compilers always think m[k] is unaddressable.

Another reason is making map elements addressable means the address of a map element must not be changed in its life cycle. This prevents Go compilers using more efficient algorithms to implement map. For the standard Go compiler, the internal addresses of map elements may be changed at run time.

Why elements of a non-nil slice are always addressable, even if the slice is unaddressable?

The internal type for slices is a struct like
struct {
	elements unsafe.Pointer
	length   int
	capacity int
}

Each slice indirectly references an element sequence. Although a non-nil slice is not addressable, its internal element sequence must be addressable. Taking addresses of elements of a slice is taking the addresses of elements of the internal array, in fact. This is why elements of unaddressable non-nil slices are addressable.

For the same reason, the substring operations on unaddressable strings also always compile ok (by the standard Go compiler). However, I can't make sure whether this is guaranteed by Go specification or not.

For any non-pointer non-interface defined type T, why is the method set of *T always a super set of the method set of T, but not vice versa?

In Go, for convenience,

So it is much reasonable that the method set of *T is always a super set of the method set of T, but not vice versa.

In fact, you can think for every method defined on type T, an implicit method with the same name and the same signature is automatically defined on type *T:
func (t T) MethodX(param0 ParamType0, ...) (result0 ResultType0, ...) {
	...
}

// An implicit method of *T is automatically defined as
func (pt *T) MethodX(param0 ParamType0, ...) (result0 ResultType0, ...) {
	return (*pt).MethodX(param0, ...)
}

If a method is defined on type *T, no methods with the same method name can be defined on T any more. This is another explanation why the method set of *T is always a super set of the method set of T, but not vice versa.

(Please read this answer in the official Go FAQ to get more explanations.)

Which types can we implement methods for?

In Go, we can only implement methods for any type T and type *T, where T

How to declare immutable values in Go?

There are three immutable value definitions:
  1. the values which have no addresses (so they are not addressable).
  2. the values which have addresses but are not addressable (their addresses are not allowed to be taken in syntax).
  3. the values which are addressable but their values are not allowed to be modified in syntax.

In Go, up to now (Go 10), there are no values satisfy the third definition. In other words, the third definition is not supported.

Part of the values satisfy the first definition in Go are called constants. In Go, only bool, numeric and string values can be declared as constants.

Methods and package-level functions can also viewed as declared immutable values. They satisfy the second definition.

There are no ways to declare other custom immutable values in Go.

Why isn't there a built-in set type?

Sets are just maps but don't care about element values. In Go, map[Tkey]struct{} is often used as a set type.

What is byte? What is rune? How to convert []byte and []rune values to strings?

In Go, byte is an alias of type uint8. In other words, byte and uint8 are the same identical type. The same relation is for rune and int32.

A rune often is used to store a Unicode break point.

[]byte and []rune values can be converted to string, directly but explicitly, and vice versa:
package main

import "fmt"

func main() {
	var s0 = "Go"
	
	var bs = []byte(s0)
	var s1 = string(bs)
	
	var rs = []rune(s0)
	var s2 = string(rs)
	
	fmt.Println(s0 == s1) // true
	fmt.Println(s0 == s2) // true
}

About more on strings, please read strings in Go.

What does iota mean?

Iota is the ninth letter of the Greek alphabet. In Go, iota is used in numeric constant declarations. In any constant declaration groups, the initial value of iota is 0, and it will increase by one, line by line.

Why isn't there a built-in closed function to check whether or not a channel is closed?

The reason is the usefulness of such function is very limited. The return result of a call to such function may be not able to reflect the latest status of the input channel. So it is not a good idea to make decisions relying on the return result.

If you do need such a function, it would be effortless to write one by yourself. Please read this article to get how to write closed functions and how to avoid using such a function.

Is it safe for a function to return pointers of local variables?

Yes, it is absolutely safe in Go.

Go compilers which support stack will do escape analysis. For the standard Go compiler, if the escape analyzer thinks a memory block will only be used in current function call for sure, it will allocate the memory block on stack, otherwise, then the memory block will be allocated on heap.

What does the word gopher mean in Go community?

In Go community, a gopher means a Go programmer. This nickname may be originated from the fact that Go language adopted a cartoon gopher as the mascot. BTW, the cartoon gopher is designed by Renee French, who is the wife of the Go project leader, Rob Pike.

The Go 101 project is hosted on both github and gitlab. Welcome to improve Go 101 articles by submitting corrections for all kinds of mistakes, such as typos, grammar errors, wording inaccuracies, description flaws and code bugs.