Разница в типе переменной, когда переменные аргументы напрямую добавляются к фрагменту, чем при добавлении по отдельности в цикл for

#go #type-assertion

# #Вперед #тип-утверждение

Вопрос:

При попытке имитировать интерфейс очереди в go lang, в методе Enque я добавлял переменные аргументы непосредственно к фрагменту. Но при извлечении в операции Deque утверждение типа выдавало ошибку паники. Как добавление переменных аргументов непосредственно в срез отличается от добавления их по отдельности?

 type Queue struct {
    queueItems []Item
}

func (queue *Queue) Enque(items ...Item) error {
    ...
    queue.queueItems = append(queue.queueItems, items)
    ...
}

....
queue.Enque(200)
val := queue.Deque()
otherVal := val.(int)
.....
 

Приведенный ниже код для Enque работает нормально

 func (queue *Queue) Enque(items ...Item) error {
  ....
    for _, itemVal := range items {
        queue.queueItems = append(queue.queueItems, itemVal)
    }
  ....
}
 

Комментарии:

1. Если вы хотите добавить все элементы по отдельности, используйте queue.queueItems = append(queue.queueItems, items...) . Ваша версия добавляется items как отдельный элемент.

Ответ №1:

Когда вы определяете формальный параметр переменной для функции, базовый тип фактического параметра, когда вы используете его в функции, является фрагментом любого указанного вами типа. В этом случае формальный параметр items in Enqueue при использовании в функции преобразуется в тип []Item (slice of Item ).

Поэтому, когда вы пишете queue.queueItems = append(queue.queueItems, items) , то, что вы на самом деле говорите, — это добавить весь этот фрагмент элементов как отдельный элемент к моему фрагменту.

То, что вы хотели сделать, это добавить каждый элемент из параметра variadic в виде отдельных элементов в свой срез, чего вы можете достичь следующим образом: queue.queueItems = append(queue.queueItems, items...)