На практике не часто сталкиваешься с массивами из-за ограниченной длины при строгой типизации. Вместо этого повсеместно используются слайсы. Слайс — это массив неопределенной длины (или динамический массив):
var nums = []int{1, 2, 3}
nums := []int{1, 2, 3}
Чтение и запись осуществляется точно так же как в массивах:
nums := []int{1, 2, 3}
nums[2] // 3
nums[0] = 10 // [10, 2, 3]
nums[:2] // [10, 2]
В слайсы можно добавлять элементы с помощью встроенной функции func append(slice []Type, elems ...Type) []Type
, которая возвращает новый слайс с добавленным элементом:
words := []string{"hello"}
words = append(words, "world") // ["hello", "world"]
Так как слайс имеет нефиксированную длину, "под капотом" лежит более сложная структура, чем у массива. Помимо самих значений слайс хранит 2 дополнительных свойства: длину массива len (длина) и cap (вместимость). Благодаря этому возможно инициализировать слайс нужной длины с помощью встроенной функции func make(t Type, len, cap IntegerType) Type
. Понимание, где лучше использовать какой способ инициализации, приходит с опытом, но для старта рекомендуется использовать make
везде, где можно:
// len = 5. Массив сразу будет заполнен 5-ю нулевыми значениями
nums := make([]int, 5, 5) // [0, 0, 0, 0, 0]
// len = 0, но cap = 5. Массив будет пустым, однако заполнение слайса через append будет эффективным, потому что в памяти уже выделен массив нужной длины
nums := make([]int, 0, 5) // []
Передача слайса как аргумента функции происходит хитро. Длина и вместимость передаются по значению, но массив значений передается по ссылке. Вследствие этого получается неявное поведение: добавленные элементы не сохранятся в исходный слайс, но изменение существующих останется:
package main
import (
"fmt"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
modifySlice(nums)
fmt.Println(nums) // [1 2 10 4 5]
}
func modifySlice(nums []int) {
nums[2] = 10 // элемент будет и в исходном слайсе
nums = append(nums, 6) // элемент не добавится в исходный слайс
}
Реализуйте функцию RemoveFirstElement(slice []int) []int
, которая удаляет первый элемент из слайса. Если в функцию передан пустой слайс, то функция также вернет пустой слайс.
original := []int{1, 2, 3, 4, 5}
RemoveFirstElement(original) // [2 3 4 5]
RemoveFirstElement([]int{}) // []
Команда проекта находится в телеграм-сообществе по ссылке https://ttttt.me/HexletLearningBot. Там можно задать любой вопрос и повлиять на проект
Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "Обсуждение". Как правильно задать вопрос:
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества
Привет! Я Тота и моя задача помочь в обучении. Чтобы активировать меня, нужно зарегистрироваться или залогиниться, если у вас уже есть аккаунт
Ваше упражнение проверяется по этим тестам
1package solution
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/assert"
7)
8
9func TestRemoveFirstElement(t *testing.T) {
10 a := assert.New(t)
11 a.Equal([]int{2, 3, 4}, RemoveFirstElement([]int{1, 2, 3, 4}))
12 a.Equal([]int{}, RemoveFirstElement([]int{}))
13 a.Equal([]int{-3, -2}, RemoveFirstElement([]int{-4, -3, -2}))
14 a.Equal([]int{}, RemoveFirstElement([]int{3}))
15}
16
Решение учителя откроется через: