在golang中包含整数和nil值的数组?
I am new to golang. But I couldn't find an answer to this.
In python I can do,
array = [1, 2, 3, None, 5]
But in go when I write
var array = [5]int {1, 2, 3, nil, 5}
The compiler gives me the following error:
cannot convert nil to type int
How can I create an array in golang which is a mix of integer and nil values?
我是golang的新手。 但是我找不到答案。 p>
在python中,我可以做 p>
array = [1、2、3,无,5]
code> pre>
但是我写 p>
var数组= [5] int {1,2,3,nil,5} \ n code> pre>
编译器给我以下错误: p>
无法将nil转换为int
code>类型 pre>
如何在golang中创建一个由整数和nil值混合而成的数组? p>
div>
First a bit of theory. Python is a dynamically typed language. While each individual value has a type, your variables can be assigned values of any type without a problem. As a consequence, python collections can contain multiple types of values and don't complain. The following is a valid python tuple (1, 'a', None, True)
. Go is a statically typed language. If your variable is defined as an integer you cannot assign any non-integer value to it. As a consequence, collections in Go have a type and can only contain a single type of object.
Now to practice. There are a few ways to do what you want. The classical C way would be to pick an integer value you are never going to encounter and use that as a null value. A 0 or a -1 or something. This is not very robust though.
A more idiomatic way is to define your own type.
package main
import "fmt"
type NilInt struct {
value int
null bool
}
func (n *NilInt) Value() interface{} {
if n.null {
return nil
}
return n.value
}
func NewInt(x int) NilInt {
return NilInt{x, false}
}
func NewNil() NilInt {
return NilInt{0, true}
}
func main() {
var x = []NilInt{NewNil(), NewInt(10), NewNil(), NewInt(5)}
for _, i := range x {
fmt.Printf("%v ", i.Value())
}
}
Every type in go has a "zero value" which it is assigned when it is created to make sure it is always initialized. For int the "zero value" is 0, for strings "". There are some things that can have nil
as their value though:
- pointers
- interfaces
- maps
- slices
- channels
- function types
Only the first is really relevant here though. If you want an int that is nil you have to declare it as a pointer to that int. As slices can't have mixed types you then need to make the slice a slice of type pointer to int: *int
. So you could have a slice of pointers to ints that included a nil value:
zero := 0
ints := []*int{&zero, nil}
for _, anInt := range ints {
if anInt != nil {
fmt.Println(*anInt)
} else {
fmt.Println(anInt)
}
}
The *anInt
in the println dereferences the pointer turning it into an int
rather than a pointer to an int
.