WTF is nil ?
nil Is the zero value for pointers, interfaces, maps, slices, channels and function types, representing an uninitialized value.
nil serves a similar purpose in the language’s type system.
var p *int // p is a nil pointer
var s []int // s is a nil slice
var m map[string]int // m is a nil map
var ch chan int // ch is a nil channel
var fn func() // fn is a nil function
var i interface{} // i is a nil interface
fmt.Println(p == nil) // true
fmt.Println(s == nil) // trueTip
nilis usually mistaken as null (or NULL) in other languages, but they are different.
nilcan be used without declaring it.
nil != null
import "fmt"
func main() {
// Your code goes here inside the main function
var ptr *int
fmt.Println(ptr) // Outputs: <nil>
// var n = nil // nil is untyped
isNil()
}
func isNil() {
var i *int = nil
var j *int = nil
if i == j {
fmt.Println("equal")
} else {
fmt.Println("no")
}
}
// Output
// <nil>
// equalnil Can represent Zero values of the following kinds of types:
-
pointer types
-
map types
-
slice types
-
function types
-
channel types
-
interface types
-
Predeclared
nilhas not a Default type.- the default types of
trueandfalseare bothbooltype.
- the default types of
-
nilIs not a keyword.(BTW,nullandNULLin many other languages are also not keywords.)
nil := 123
fmt.Println(nil) // 123- The Sizes of Nil Values With Types of Different Kinds May Be Different
nil is Untyped
nil has no default type on its own. You must assign it to something that has a type, and then it takes on that context.
var p *int = nil // now `nil` is treated as *int
var s []string = nil // now `nil` is treated as []string
var ch chan int = nil // now `nil` is treated as chan int
fmt.Println(nil) // ❌ ERROR: use of untyped nilUsage
1. Pointers
nil represents a pointer that does not point to any memory location. A nil pointer does not hold a valid memory address.
- Example:
var ptr *int // ptr is nil by default
if ptr == nil {
fmt.Println("Pointer is nil")
}2. Interfaces
var i interface{}
if i == nil {
fmt.Println("Interface is nil")
}3. Slices
var s []int
if s == nil {
fmt.Println("Slice is nil")
}6. Functions
var f func()
if f == nil {
fmt.Println("Function is nil")
}7. Error Handling
func someFunc() error {
// Do something
return nil // No error
}WTF is _ Blank Identifier ?
Effective Go - The Go Programming Language
- The blank identifier can be assigned or declared with any value of any type, with the value discarded harmlessly.
- It’s a bit like writing to the Unix
/dev/nullfile. - it represents a write-only value to be used as a place-holder where a variable is needed but the actual value is irrelevant.
1. Ignoring Unused Return Values
value, _ := someFunction() // Ignore the second return value2. Ignoring Errors
result, _ := strconv.Atoi("123") // Ignore the error for simplicity3. Loop Iteration without Index
values := []int{10, 20, 30}
for _, v := range values {
fmt.Println(v) // Only using the value, ignoring the index
}4. Assigning to Blank Identifier to Avoid “Declared But Not Used” Error
result := someComputation()
_ = result // Avoid unused variable error5. Ignoring Values in map Ranges
myMap := map[string]int{"a": 1, "b": 2}
for _, v := range myMap {
fmt.Println(v) // Only using the value, ignoring the key
}6. Implementing Interfaces Partially
var _ SomeInterface = (*MyStruct)(nil) // Ensures MyStruct implements SomeInterface7. Using Blank Identifier with import to Import a Package for Side Effects Only
import _ "net/http/pprof" // Import for side effects only8. Placeholder in Multiple Assignment (Sometimes)
a, _, c := someFunc() // Ignore the second value