Инициализировать массив указателей - нельзя сделать тип * [] типом - PullRequest
0 голосов
/ 06 июля 2019

Простой код, сохраняющий объекты типа car в массив типа car. Я пытаюсь использовать указатель здесь для передачи ссылки на массив.

Есть 2 проблемы:

1 - Я не могу инициализировать его как пустой массив. Когда я использую make, он говорит:

не может сделать тип * [] автомобиль

2 - Если я не использую make, возникает ошибка времени выполнения:

паника: ошибка во время выполнения: неверный адрес памяти или разыменование нулевого указателя


Код:

import "fmt"

type car struct {
    plate string
    color string
}

func main() {

    var _cars *[]car        // list of cars
    _cars = make(*[]car, 4) // initialize empty cars list

    saveCar(_cars, car{"ABC-123", "Black"})
    saveCar(_cars, car{"ABC-456", "Black"})
    saveCar(_cars, car{"ABC-789", "Black"})

    fmt.Println(_cars)
}

func saveCar(_cars_list *[]car, _car car) int {

    for index, current := range *_cars_list {
        // if empty place found, save car
        if (car{}) == current {

            // save car
            (*_cars_list)[index] = _car

            // return the saved index
            return index
        }
    }

    return -1
}

Ответы [ 2 ]

1 голос
/ 06 июля 2019

Изменение этого параметра заставит ваш код работать:

tCars := make([]car, 4)
_cars = &tCars
1 голос
/ 06 июля 2019

1 - не может сделать тип * [] автомобиль

Вы наблюдаете это, потому что make создает срез, карту или чан. В приведенном вами примере вы пытались создать указатель на фрагмент, с которым не работает ни один из напечатанных make.

2 - Если я не использую make, возникает ошибка во время выполнения:

это еще одна проблема - у вас есть тип «указатель на кусочек автомобиля», а не «кусочек автомобиля». И вообще вам нужно инициализировать типы указателей перед использованием.

В целом, в вашем случае нет необходимости использовать указатель на срез, а не обычный срез, потому что вы не используете append, чтобы не было возможности перераспределить резервное хранилище.

Однако в реальном сценарии, когда вы не знаете, сколько экземпляров автомобилей вы собираетесь добавить, гораздо лучше использовать append, а не перебирать слайс до последнего неинициализированного значения.

Резюме:

  • чтобы ваша программа работала, меняйте * [] автомобиль на [] автомобиль везде (пример https://play.golang.org/p/lpCtvXqG6UY)
  • другой (и, возможно, лучший) способ - использовать append вместо saveCar (не забудьте использовать возвращаемое значение в случае перераспределения, например: https://play.golang.org/p/L8V10tSb-IJ)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...