Golang: Структуры в срезах
В Go часто возникает необходимость хранить набор однотипных структур. Для этого удобно использовать срезы структур. Такой подход позволяет работать с коллекцией объектов, каждый из которых имеет одинаковый набор полей.
Объявление среза структур
Срез структур можно объявить так же, как и срез базовых типов:
type User struct {
Name string
Email string
}
func main() {
users := []User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@example.com"},
}
for _, u := range users {
fmt.Println(u.Name, u.Email)
}
}Добавление новых элементов
Элементы добавляются с помощью append:
users = append(users, User{Name: "Алексей", Email: "alex@example.com"})Изменение значений внутри среза
Так как срез хранит копии структур, при изменении элемента важно помнить о передаче по значению. Например:
users[0].Name = "Семен Иванов"Изменение произойдет напрямую, так как мы работаем с элементом по индексу.
Срез указателей на структуры
Если нам нужно хранить и изменять объекты по ссылке, можно использовать срез указателей:
type User struct {
Name string
Email string
}
func main() {
users := []*User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@example.com"},
}
users[0].Name = "Семен Иванов" // Изменение отразится на оригинальном объекте
}Использование указателей полезно, если структуры большие и их копирование неэффективно.
Поиск и фильтрация
Для поиска элементов в срезе структур можно использовать обычные циклы:
func FindUserByEmail(users []User, email string) *User {
for i := range users {
if users[i].Email == email {
return &users[i]
}
}
return nil
}Задание
Создайте функцию FindUserNames(), которая принимает срез структур User и возвращает срез имен всех пользователей, у которых email оканчивается на @example.com.
-
Структура
Userуже объявлена:type User struct { Name string Email string } -
Если пользователей с таким email нет, функция должна вернуть пустой срез (а не
nil). -
Порядок имен в возвращаемом срезе должен соответствовать исходному порядку.
Пример
users := []User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@gmail.com"},
{Name: "Алексей", Email: "alex@example.com"},
}
names := FindUserNames(users)
// Ожидаемый результат: []string{"Семен", "Алексей"}Golang: Структуры в срезах
В Go часто возникает необходимость хранить набор однотипных структур. Для этого удобно использовать срезы структур. Такой подход позволяет работать с коллекцией объектов, каждый из которых имеет одинаковый набор полей.
Объявление среза структур
Срез структур можно объявить так же, как и срез базовых типов:
type User struct {
Name string
Email string
}
func main() {
users := []User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@example.com"},
}
for _, u := range users {
fmt.Println(u.Name, u.Email)
}
}Добавление новых элементов
Элементы добавляются с помощью append:
users = append(users, User{Name: "Алексей", Email: "alex@example.com"})Изменение значений внутри среза
Так как срез хранит копии структур, при изменении элемента важно помнить о передаче по значению. Например:
users[0].Name = "Семен Иванов"Изменение произойдет напрямую, так как мы работаем с элементом по индексу.
Срез указателей на структуры
Если нам нужно хранить и изменять объекты по ссылке, можно использовать срез указателей:
type User struct {
Name string
Email string
}
func main() {
users := []*User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@example.com"},
}
users[0].Name = "Семен Иванов" // Изменение отразится на оригинальном объекте
}Использование указателей полезно, если структуры большие и их копирование неэффективно.
Поиск и фильтрация
Для поиска элементов в срезе структур можно использовать обычные циклы:
func FindUserByEmail(users []User, email string) *User {
for i := range users {
if users[i].Email == email {
return &users[i]
}
}
return nil
}Задание
Создайте функцию FindUserNames(), которая принимает срез структур User и возвращает срез имен всех пользователей, у которых email оканчивается на @example.com.
-
Структура
Userуже объявлена:type User struct { Name string Email string } -
Если пользователей с таким email нет, функция должна вернуть пустой срез (а не
nil). -
Порядок имен в возвращаемом срезе должен соответствовать исходному порядку.
Пример
users := []User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@gmail.com"},
{Name: "Алексей", Email: "alex@example.com"},
}
names := FindUserNames(users)
// Ожидаемый результат: []string{"Семен", "Алексей"}Ваше упражнение проверяется по этим тестам
package solution
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFindUserNames(t *testing.T) {
users := []User{
{Name: "Семен", Email: "semen@example.com"},
{Name: "Юля", Email: "yulia@gmail.com"},
{Name: "Алексей", Email: "alex@example.com"},
}
expected := []string{"Семен", "Алексей"}
result := FindUserNames(users)
assert.Equal(t, expected, result, "Должны быть возвращены только пользователи с email @example.com")
}
func TestFindUserNamesEmpty(t *testing.T) {
users := []User{
{Name: "Юля", Email: "yulia@gmail.com"},
{Name: "Виктор", Email: "victor@mail.ru"},
}
expected := []string{}
result := FindUserNames(users)
assert.Equal(t, expected, result, "Если нет email с @example.com, должен вернуться пустой срез")
}Решение учителя откроется через:
20:00
