Golang: Слайсы из срезов
В Go есть удобная операция слайсинг (slicing), которая используется для получения поднабора элементов из среза. С помощью конструкции [:] можно указать диапазон элементов, создавая новый срез, который ссылается на тот же базовый массив. При этом операция не копирует данные, а лишь формирует новое «окно» на существующий массив.
Как работает слайсинг [:]
Синтаксис:
s[начало:конец]начало— индекс, с которого начинается срез (включительно).конец— индекс, на котором срез заканчивается (не включительно).- Если
началоне указано — берется0. - Если
конецне указан — беретсяlen(s).
Примеры
s := []int{10, 20, 30, 40, 50}
fmt.Println(s[:]) // => [10 20 30 40 50]
fmt.Println(s[1:4]) // => [20 30 40]
fmt.Println(s[:3]) // => [10 20 30]
fmt.Println(s[2:]) // => [30 40 50]Отрезание элементов
Срезы позволяют легко отбросить первый или последний элемент:
s := []string{"a", "b", "c", "d"}
s = s[1:] // убираем первый элемент
fmt.Println(s) // => [b c d]
s = s[:len(s)-1] // убираем последний элемент
fmt.Println(s) // => [b c]Вложенные срезы
Так как [:] возвращает новый срез, можно использовать его в цепочках:
s := []int{1, 2, 3, 4, 5}
middle := s[1:4] // [2 3 4]
tail := middle[1:] // [3 4]
fmt.Println(tail) // => [3 4]Важно: все срезы указывают на один и тот же базовый массив. Изменение элемента в одном срезе повлияет на другие.
s := []int{1, 2, 3, 4}
sub := s[1:3] // [2 3]
sub[0] = 99
fmt.Println(s) // => [1 99 3 4]Выход за пределы
Если задать границы, выходящие за пределы длины среза, будет паника времени выполнения:
s := []int{1, 2, 3}
fmt.Println(s[1:5]) // panic: slice bounds out of rangeИспользование [:] для "удаления" элементов
В Go нет встроенной функции для удаления элементов из среза, но [:] позволяет легко получить новый срез без нужных элементов.
Удаление первого элемента
s := []string{"a", "b", "c", "d"}
s = s[1:]
fmt.Println(s) // => [b c d]Удаление последнего элемента
s := []string{"a", "b", "c", "d"}
s = s[:len(s)-1]
fmt.Println(s) // => [a b c]Удаление диапазона элементов
Можно отбросить несколько элементов, используя append() вместе с [:]:
s := []string{"a", "b", "c", "d", "e"}
s = append(s[:1], s[3:]...)
fmt.Println(s) // => [a d e]Конструкция [:] в таких примерах не копирует данные, а создаёт новый срез с нужным диапазоном, сохраняя общую память с исходным массивом.
Кратко
| Операция | Синтаксис | Результат |
|---|---|---|
| Весь срез | s[:] | Все элементы |
От начала до индекса n | s[:n] | Элементы с индексами 0 до n-1 |
От индекса i до конца | s[i:] | Элементы от i до конца |
Диапазон от i до j | s[i:j] | Элементы с индексами i до j-1 |
| Удалить первый элемент | s[1:] | Все, кроме первого |
| Удалить последний элемент | s[:len(s)-1] | Все, кроме последнего |
Задание
Реализуйте функцию GetWorkHours(schedule []int) []int, которая принимает срез schedule, где каждый элемент — это количество рабочих часов за день недели (с понедельника по воскресенье). Функция должна вернуть рабочие часы только за будние дни (понедельник–пятница). Если данных меньше пяти элементов, вернуть пустой срез.
Примеры
GetWorkHours([]int{8, 8, 8, 8, 6, 0, 0}) // [8 8 8 8 6]
GetWorkHours([]int{8, 8, 8, 8}) // []
GetWorkHours([]int{}) // []Golang: Слайсы из срезов
В Go есть удобная операция слайсинг (slicing), которая используется для получения поднабора элементов из среза. С помощью конструкции [:] можно указать диапазон элементов, создавая новый срез, который ссылается на тот же базовый массив. При этом операция не копирует данные, а лишь формирует новое «окно» на существующий массив.
Как работает слайсинг [:]
Синтаксис:
s[начало:конец]начало— индекс, с которого начинается срез (включительно).конец— индекс, на котором срез заканчивается (не включительно).- Если
началоне указано — берется0. - Если
конецне указан — беретсяlen(s).
Примеры
s := []int{10, 20, 30, 40, 50}
fmt.Println(s[:]) // => [10 20 30 40 50]
fmt.Println(s[1:4]) // => [20 30 40]
fmt.Println(s[:3]) // => [10 20 30]
fmt.Println(s[2:]) // => [30 40 50]Отрезание элементов
Срезы позволяют легко отбросить первый или последний элемент:
s := []string{"a", "b", "c", "d"}
s = s[1:] // убираем первый элемент
fmt.Println(s) // => [b c d]
s = s[:len(s)-1] // убираем последний элемент
fmt.Println(s) // => [b c]Вложенные срезы
Так как [:] возвращает новый срез, можно использовать его в цепочках:
s := []int{1, 2, 3, 4, 5}
middle := s[1:4] // [2 3 4]
tail := middle[1:] // [3 4]
fmt.Println(tail) // => [3 4]Важно: все срезы указывают на один и тот же базовый массив. Изменение элемента в одном срезе повлияет на другие.
s := []int{1, 2, 3, 4}
sub := s[1:3] // [2 3]
sub[0] = 99
fmt.Println(s) // => [1 99 3 4]Выход за пределы
Если задать границы, выходящие за пределы длины среза, будет паника времени выполнения:
s := []int{1, 2, 3}
fmt.Println(s[1:5]) // panic: slice bounds out of rangeИспользование [:] для "удаления" элементов
В Go нет встроенной функции для удаления элементов из среза, но [:] позволяет легко получить новый срез без нужных элементов.
Удаление первого элемента
s := []string{"a", "b", "c", "d"}
s = s[1:]
fmt.Println(s) // => [b c d]Удаление последнего элемента
s := []string{"a", "b", "c", "d"}
s = s[:len(s)-1]
fmt.Println(s) // => [a b c]Удаление диапазона элементов
Можно отбросить несколько элементов, используя append() вместе с [:]:
s := []string{"a", "b", "c", "d", "e"}
s = append(s[:1], s[3:]...)
fmt.Println(s) // => [a d e]Конструкция [:] в таких примерах не копирует данные, а создаёт новый срез с нужным диапазоном, сохраняя общую память с исходным массивом.
Кратко
| Операция | Синтаксис | Результат |
|---|---|---|
| Весь срез | s[:] | Все элементы |
От начала до индекса n | s[:n] | Элементы с индексами 0 до n-1 |
От индекса i до конца | s[i:] | Элементы от i до конца |
Диапазон от i до j | s[i:j] | Элементы с индексами i до j-1 |
| Удалить первый элемент | s[1:] | Все, кроме первого |
| Удалить последний элемент | s[:len(s)-1] | Все, кроме последнего |
Задание
Реализуйте функцию GetWorkHours(schedule []int) []int, которая принимает срез schedule, где каждый элемент — это количество рабочих часов за день недели (с понедельника по воскресенье). Функция должна вернуть рабочие часы только за будние дни (понедельник–пятница). Если данных меньше пяти элементов, вернуть пустой срез.
Примеры
GetWorkHours([]int{8, 8, 8, 8, 6, 0, 0}) // [8 8 8 8 6]
GetWorkHours([]int{8, 8, 8, 8}) // []
GetWorkHours([]int{}) // []Ваше упражнение проверяется по этим тестам
package solution
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetWorkHours(t *testing.T) {
tests := []struct {
name string
input []int
expected []int
}{
{
name: "Full week",
input: []int{8, 8, 8, 8, 6, 0, 0},
expected: []int{8, 8, 8, 8, 6},
},
{
name: "Only five days",
input: []int{9, 9, 9, 9, 9},
expected: []int{9, 9, 9, 9, 9},
},
{
name: "Less than five days",
input: []int{8, 8, 8, 8},
expected: []int{},
},
{
name: "Empty schedule",
input: []int{},
expected: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := GetWorkHours(tt.input)
assert.Equal(t, tt.expected, result)
})
}
}Решение учителя откроется через:
20:00
