Why can't a string be nil in Go?

GoVariable Assignment

Go Problem Overview


The program available on The Go Playground reads

package main

import "fmt"

func main() {
	var name string = nil
	fmt.Println(name)
}

and yields an error

prog.go:6: cannot use nil as type string in assignment

I understand "" is the "zero value" for strings. I don't understand why I cannot assign nil to my string.

Go Solutions


Solution 1 - Go

The simple answer is that nil is not defined to be a valid value for type string in the language specification.

...but maybe you want a longer answer?

nil is the zero value for pointers, interfaces, channels, slices, maps and function types, and it represents an uninitialized state.

Consider the following variable declarations:

var a *SomeType
var b interface{}
var c func()

It seems natural that all these variables would have a value that represents uninitialized state. a has been declared as a pointer, but what would it point to, when we haven't yet pointed it at anything? nil is an obvious zero value for these types.

As for channels, slices and maps, their zero value is nil for the simple reason that their implementation is such that they must be explicitly initialized before they can be used. This is mostly for performance reasons, these types are all represented internally as more or less complex data structures, and initializing them is not free.

However, a string doesn't require initialization, and it seems natural that the default, zero value for a new string variable would be an empty string, "". Therefore there's simply no reason for nil to be a valid string value, and adding it to the specification would only make the language more complicated and much more cumbersome to work with.

Furthermore, what would nil of type string represent? An empty string? We already have that. An uninitialized string? There's no such thing.

Solution 2 - Go

In go string is a data type, it's no a pointer to an array like C/C++. As such you can't assign it to nil.

Solution 3 - Go

Because Golang string is a read-only slices of bytes.

However, a pointer to a string (*string) can be nil:

var s *string
s = nil
readonly := "readonly"
s = &readonly
dereference := *s

https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html

Solution 4 - Go

Aedolon made some good points, but to go further, in other languages strings are convenient ways of representing arrays of bytes as characters. We need to do this a lot, so this specific use case of an array gets a lot of language support to make it easier to use. However, at the heart of the matter, you are working with an array, which is often able to be null in a language because it is a reference type. That is, the string isn't really null, the pointer to the array is null. Because many languages conflate these two things, programmers are used to having to check if a string is null before using it.

Go doesn't do this. A string cannot be nil, because the data structure in go doesn't allow it. You can have a pointer to a byte array holding character representations in go be null, but that isn't a string.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser319286View Question on Stackoverflow
Solution 1 - GoLemurFromTheIdView Answer on Stackoverflow
Solution 2 - GoGarManView Answer on Stackoverflow
Solution 3 - GoRocketKittensView Answer on Stackoverflow
Solution 4 - GoRoger HillView Answer on Stackoverflow