Golang: Цикл for и срезы
Циклы в Go — основной инструмент для обхода срезов и работы с их элементами. Для этого можно использовать классический for с индексом, который даёт полный контроль и позволяет напрямую изменять значения, или лаконичный range, упрощающий перебор элементов и повышающий читаемость кода.
Обход среза по индексу
names := []string{"Alice", "Bob", "Charlie"}
for i := 0; i < len(names); i++ {
fmt.Println(names[i])
}- Полный контроль над индексами.
- Подходит для изменения значений:
nums := []int{1, 2, 3} for i := 0; i < len(nums); i++ { nums[i] *= 2 } fmt.Println(nums) // [2 4 6]
Обход среза с помощью range
langs := []string{"Go", "Rust", "Python"}
for i, lang := range langs {
fmt.Printf("langs[%d] = %s\n", i, lang)
}- Цикл
rangeвозвращает индекс и копию значения. - Упрощает синтаксис.
- Хорошо читается.
- Подходит для большинства задач обхода
Если не нужен индекс:
for _, lang := range langs {
fmt.Println(lang)
}Если не нужно значение:
for i := range langs {
fmt.Println(i)
}Изменение значений в range
Важно: переменная lang — это копия значения. Изменения не повлияют на оригинальный срез:
for _, lang := range langs {
lang = strings.ToUpper(lang) // изменится копия, не оригинал
}
fmt.Println(langs) // => ["Go" "Rust" "Python"]Чтобы изменить элементы, нужно использовать индекс:
for i := range langs {
langs[i] = strings.ToUpper(langs[i])
}
fmt.Println(langs) // => ["GO" "RUST" "PYTHON"]Вывод
| Способ | Изменение значений | Контроль над порядком | Краткость |
|---|---|---|---|
| По индексу | Да | Да | Нет |
Через range | Только через индекс | Нет | Да |
Цикл range — стандарт для чтения, for с индексом — для изменения.
Задание
Реализуйте функцию FilterExpensiveOrders(orders []int, limit int) []int. Она должна возвращать новый срез, содержащий только те заказы, сумма которых строго больше значения limit. Если в функцию передан пустой срез или нет заказов выше лимита, функция должна вернуть пустой срез.
Примеры:
orders := []int{120, 35, 70, 400, 15, 220, 90}
FilterExpensiveOrders(orders, 100) // [120 400 220]
FilterExpensiveOrders([]int{}, 100) // []
FilterExpensiveOrders([]int{10, 20, 30}, 100) // []Golang: Цикл for и срезы
Циклы в Go — основной инструмент для обхода срезов и работы с их элементами. Для этого можно использовать классический for с индексом, который даёт полный контроль и позволяет напрямую изменять значения, или лаконичный range, упрощающий перебор элементов и повышающий читаемость кода.
Обход среза по индексу
names := []string{"Alice", "Bob", "Charlie"}
for i := 0; i < len(names); i++ {
fmt.Println(names[i])
}- Полный контроль над индексами.
- Подходит для изменения значений:
nums := []int{1, 2, 3} for i := 0; i < len(nums); i++ { nums[i] *= 2 } fmt.Println(nums) // [2 4 6]
Обход среза с помощью range
langs := []string{"Go", "Rust", "Python"}
for i, lang := range langs {
fmt.Printf("langs[%d] = %s\n", i, lang)
}- Цикл
rangeвозвращает индекс и копию значения. - Упрощает синтаксис.
- Хорошо читается.
- Подходит для большинства задач обхода
Если не нужен индекс:
for _, lang := range langs {
fmt.Println(lang)
}Если не нужно значение:
for i := range langs {
fmt.Println(i)
}Изменение значений в range
Важно: переменная lang — это копия значения. Изменения не повлияют на оригинальный срез:
for _, lang := range langs {
lang = strings.ToUpper(lang) // изменится копия, не оригинал
}
fmt.Println(langs) // => ["Go" "Rust" "Python"]Чтобы изменить элементы, нужно использовать индекс:
for i := range langs {
langs[i] = strings.ToUpper(langs[i])
}
fmt.Println(langs) // => ["GO" "RUST" "PYTHON"]Вывод
| Способ | Изменение значений | Контроль над порядком | Краткость |
|---|---|---|---|
| По индексу | Да | Да | Нет |
Через range | Только через индекс | Нет | Да |
Цикл range — стандарт для чтения, for с индексом — для изменения.
Задание
Реализуйте функцию FilterExpensiveOrders(orders []int, limit int) []int. Она должна возвращать новый срез, содержащий только те заказы, сумма которых строго больше значения limit. Если в функцию передан пустой срез или нет заказов выше лимита, функция должна вернуть пустой срез.
Примеры:
orders := []int{120, 35, 70, 400, 15, 220, 90}
FilterExpensiveOrders(orders, 100) // [120 400 220]
FilterExpensiveOrders([]int{}, 100) // []
FilterExpensiveOrders([]int{10, 20, 30}, 100) // []Ваше упражнение проверяется по этим тестам
package solution
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFilterExpensiveOrders(t *testing.T) {
tests := []struct {
name string
orders []int
limit int
expected []int
}{
{
name: "Orders above limit",
orders: []int{120, 35, 70, 400, 15, 220, 90},
limit: 100,
expected: []int{120, 400, 220},
},
{
name: "No orders above limit",
orders: []int{10, 20, 30},
limit: 100,
expected: []int{},
},
{
name: "Empty orders list",
orders: []int{},
limit: 100,
expected: []int{},
},
{
name: "All orders above limit",
orders: []int{200, 300, 400},
limit: 100,
expected: []int{200, 300, 400},
},
{
name: "Orders equal to limit are excluded",
orders: []int{50, 100, 150},
limit: 100,
expected: []int{150},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := FilterExpensiveOrders(tt.orders, tt.limit)
assert.Equal(t, tt.expected, result)
})
}
}Решение учителя откроется через:
20:00
