Массив с целыми числами и значениями nil в golang? - PullRequest
0 голосов
/ 21 сентября 2018

Я новичок в Голанге.Но я не мог найти ответ на это.

В Python я могу сделать,

array = [1, 2, 3, None, 5]

Но на ходу, когда я пишу

var array = [5]int {1, 2, 3, nil, 5}

Компилятор выдает мне следующую ошибку:

cannot convert nil to type int

Как я могу создать массив в golang, который представляет собой сочетание целых и нулевых значений?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Сначала немного теории.Python - это динамически типизированный язык.В то время как каждое отдельное значение имеет тип, вашим переменным могут быть назначены значения любого типа без проблем.Как следствие, коллекции Python могут содержать несколько типов значений и не жаловаться.Ниже приведен корректный кортеж Python (1, 'a', None, True).Go - это статически типизированный язык.Если ваша переменная определена как целое число, вы не можете присвоить ей нецелое значение.Как следствие, коллекции в Go имеют тип и могут содержать только один тип объекта.

Теперь попрактикуйтесь.Есть несколько способов сделать то, что вы хотите.Классический способ Си состоит в том, чтобы выбрать целочисленное значение, с которым вы никогда не встретитесь, и использовать его как нулевое значение.0 или -1 или что-то.Хотя это не очень надежно.

Более идиотский способ - определить собственный тип.

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())
    }
}
0 голосов
/ 21 сентября 2018

Каждый тип в go имеет «нулевое значение», которое ему присваивается при его создании, чтобы убедиться, что оно всегда инициализируется.Для int "нулевое значение" равно 0, для строк "".Есть некоторые вещи, которые могут иметь nil в качестве значения:

  • указатели
  • интерфейсы
  • карты
  • фрагменты
  • каналы
  • типы функций

Хотя здесь действительно актуален только первый.Если вы хотите, чтобы int был nil, вы должны объявить его как указатель на этот int.Поскольку срезы не могут иметь смешанные типы, вам нужно сделать срез указателем типа на int: *int.Таким образом, у вас может быть фрагмент указателей на целые, который содержит значение nil:

zero := 0
ints := []*int{&zero, nil}
for _, anInt := range ints {
    if anInt != nil {
        fmt.Println(*anInt)
    } else {
        fmt.Println(anInt)
    }
}

*anInt в println разыменовывает указатель, превращая его в int, а не в указатель на int.

https://play.golang.org/

...