Golang: Карты
Карты (map
) — это встроенный тип данных в Go для хранения пар «ключ-значение». Они позволяют быстро находить, добавлять и удалять данные по ключу. Карты используются везде, где нужен ассоциативный массив или словарь.
Определение карты
Карту можно объявить без инициализации:
var ages map[string]int
Здесь map[string]int
— это тип карты, где:
- Ключ имеет тип
string
. - Значение имеет тип
int
.
Ключами в Go могут быть любые типы данных, которые сравнимы (comparable
). Это значит, что они могут использоваться в операциях ==
и !=
. Это могут быть строки, числа, булевы значения, массивы фиксированной длины и структуры со сравниваемыми полями. Срезы, карты и функции не могут быть ключами, так как они не поддерживают сравнение.
Создание карты
При объявлении карта равна nil
.
var ages map[string]int
fmt.Println(ages == nil) // => true
Чтобы начать её использовать, необходимо явно выделить память с помощью make()
:
ages := make(map[string]int)
fmt.Println(ages == nil) // => false
ages["Alice"] = 25
ages["Bob"] = 30
fmt.Println(ages) // => map[Alice:25 Bob:30]
Можно создать карту и сразу инициализировать её значениями через литерал:
scores := map[string]int{
"Tom": 90,
"Jack": 80,
}
fmt.Println(scores) // => map[Jack:80 Tom:90]
Обращение к элементам
Чтобы получить значение по ключу, используется синтаксис map[key]
:
fmt.Println(ages["Alice"]) // => 25
Если обратиться к несуществующему ключу, будет возвращено значение по умолчанию для типа, например 0
для чисел или пустая строка для string
:
// ключа "Charlie" нет
fmt.Println(ages["Charlie"]) // => 0
Проверка существования ключа
Чтобы проверить, есть ли ключ в карте, используется «двойное присваивание»:
age, exists := ages["Charlie"]
fmt.Println(age, exists) // => 0 false
Переменная exists
будет true
, если ключ найден, и false
— если нет.
Удаление элемента
Удалить элемент из карты можно с помощью встроенной функции delete()
:
delete(ages, "Alice")
fmt.Println(ages) // => map[Bob:30]
Если ключа нет, delete()
просто ничего не делает.
Размер карты
Чтобы узнать количество элементов в карте, используется len()
:
fmt.Println(len(ages)) // => 1
Задание
Реализуйте функцию GetGrade(scores map[string]int, name string) (string, error)
, которая принимает карту scores
с именами студентов и их оценками (число от 0 до 100) и имя студента name
.
Функция должна:
- Вернуть строку вида
"<имя> has <оценка> points"
, если студент найден. - Вернуть ошибку, если указанного студента нет в карте.
Примеры
scores := map[string]int{
"Tom": 90,
"Alice": 75,
}
res, err := GetGrade(scores, "Tom")
// res = "Tom has 90 points", err = nil
res, err := GetGrade(scores, "Charlie")
// res = "", err != nil
Полезное
Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект
Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества
Ваше упражнение проверяется по этим тестам
package solution
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetGrade(t *testing.T) {
scores := map[string]int{
"Tom": 90,
"Alice": 75,
}
tests := []struct {
name string
student string
want string
wantError bool
}{
{"Existing student", "Tom", "Tom has 90 points", false},
{"Another student", "Alice", "Alice has 75 points", false},
{"Non-existing student", "Charlie", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := GetGrade(scores, tt.student)
if tt.wantError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.want, result)
}
})
}
}
Решение учителя откроется через:
20:00
