🤔 Какой метод используется для декодирования JSON данных в Go?
Anonymous Quiz
82%
Unmarshal
12%
Decode
5%
Parse
2%
Deserialize
Юнит-тесты (unit tests) — это тесты, предназначенные для проверки корректности работы отдельных модулей или единиц кода, таких как функции или методы. Основная цель юнит-тестов — убедиться, что каждый модуль кода работает как ожидается. Играют ключевую роль в поддержке качества и надежности кода.
Юнит-тесты помогают выявлять ошибки и проблемы в коде на самых ранних этапах разработки, что снижает затраты на их исправление.
Хорошо написанные юнит-тесты служат живой документацией для кода, показывая, как именно должны работать функции и методы.
Наличие юнит-тестов делает процесс рефакторинга безопаснее, так как тесты помогают убедиться, что изменения в коде не нарушили его корректную работу.
Юнит-тесты обеспечивают уверенность в том, что код работает правильно, что особенно важно при добавлении новых функций или исправлении ошибок.
_test.go
.Test
и принимать один аргумент типа *testing.T
.Рассмотрим пример, где у нас есть функция, которая складывает два числа, и мы пишем для неё юнит-тест.
// main.go
package main
func Add(a, b int) int {
return a + b
}
// main_test.go
package main
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5
if result != expected {
t.Errorf("Add(2, 3) = %d; want %d", result, expected)
}
}
Чтобы запустить юнит-тесты, используйте команду
go test
в терминале.$ go test
Table-driven tests позволяют легко добавлять новые тестовые случаи и улучшать читаемость тестов.
package main
import "testing"
func TestAdd(t *testing.T) {
tests := []struct {
a, b, expected int
}{
{1, 2, 3},
{0, 0, 0},
{-1, -1, -2},
{2, 2, 4},
}
for _, tt := range tests {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
}
}
}
Лучшие практики
Каждый юнит-тест должен проверять только одну конкретную функцию или метод и проверять один аспект её поведения.
Имена тестовых функций должны быть понятными и отражать их цель. Например,
TestAdd
для тестирования функции Add
.Убедитесь, что ваши тесты проверяют крайние случаи и потенциальные ошибки, такие как нулевые значения, отрицательные числа и переполнения.
Регулярно запускайте тесты, особенно перед коммитами и релизами, чтобы убедиться в отсутствии регрессий.
При тестировании функций, которые зависят от внешних ресурсов (таких как базы данных или API), используйте мокирование (mocking) для изоляции тестов.
Юнит-тесты проверяют отдельные функции или методы на корректность их работы. Они помогают выявлять ошибки на ранней стадии, служат документацией и поддерживают безопасный рефакторинг кода. Пишутся в файлах с суффиксом
_test.go
и запускаются с помощью команды go test
.Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой метод используется для чтения содержимого файла в Go?
Anonymous Quiz
44%
Read
38%
ReadFile
17%
Open
1%
Load
Срезы (slices) — это динамические массивы, которые могут изменять свой размер. Встроенная функция
append
используется для добавления новых элементов к срезу. Основные особенности:
Могут увеличивать свой размер динамически. Когда вызывается функция
append
, если подлежащий массив не имеет достаточной емкости для размещения новых элементов, создается новый массив, и все существующие элементы копируются в него.Функция
append
изменяет длину среза, добавляя новые элементы. Емкость может также увеличиваться, если требуется больше памяти для новых элементов.append
возвращает новый срез, который включает добавленные элементы. Этот новый срез может указывать на новый массив, если емкость исходного была недостаточной.Пример:
package main
import "fmt"
func main() {
// Создание пустого среза
var s []int
// Добавление одного элемента
s = append(s, 1)
fmt.Println(s) // Output: [1]
// Добавление нескольких элементов
s = append(s, 2, 3, 4)
fmt.Println(s) // Output: [1 2 3 4]
// Добавление элементов из другого среза
t := []int{5, 6, 7}
s = append(s, t...)
fmt.Println(s) // Output: [1 2 3 4 5 6 7]
}
Проверяется, достаточно ли емкости в подлежащем массиве для размещения новых элементов. Емкость (
capacity
) среза — это размер подлежащего массива, который может быть больше, чем текущая длина (length
) среза.Если емкости недостаточно, выделяется новый массив, обычно в два раза больший, чем текущий размер.
Все существующие элементы копируются в новый массив, и новые элементы добавляются в конец.
Новый срез, указывающий на новый массив, возвращается.
Пример:
package main
import "fmt"
func main() {
// Изначальный срез с длиной 0 и емкостью 0
s := []int{}
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
// Добавление элементов и отслеживание изменений длины и емкости
for i := 1; i <= 10; i++ {
s = append(s, i)
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
}
В этом примере, когда вы добавляете элементы, емкость среза автоматически увеличивается. Вывод показывает, как длина и емкость изменяются с добавлением каждого нового элемента.
Функция
append
добавляет новые элементы к срезу, изменяя его длину. Если емкости подлежащего массива недостаточно, создается новый массив, в который копируются все элементы. Она возвращает новый срез, который может указывать на новый массив, если емкость была увеличена.Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой пакет используется для работы с регулярными выражениями в Go?
Anonymous Quiz
42%
regexp
38%
regex
10%
re
10%
reg
Интеграционные тесты — это тесты, которые проверяют взаимодействие между различными компонентами системы. В отличие от юнит-тестов, которые фокусируются на проверке отдельных функций или методов, интеграционные проверяют, как компоненты работают вместе, обеспечивая целостность и корректность всей системы.
Интеграционные тесты помогают убедиться, что различные части системы правильно взаимодействуют друг с другом. Это важно для выявления проблем на границах между компонентами, которые могут не проявиться в юнит-тестах.
Такие тесты помогают обнаруживать ошибки, возникающие при объединении модулей. Это могут быть проблемы с форматами данных, неправильное использование интерфейсов и другие ошибки, связанные с интеграцией.
Интеграционные тесты могут включать сценарии, приближенные к реальным условиям эксплуатации системы, что позволяет убедиться, что система работает правильно в реальной среде.
Интеграционные тесты могут требовать наличия нескольких зависимостей, таких как база данных, внешние API или другие сервисы. Настройте тестовую среду, которая будет эмулировать реальную среду.
Рассмотрим пример интеграционного теста для приложения, которое работает с базой данных. В этом примере мы будем тестировать функции создания и получения пользователя.
// main.go
package main
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
"log"
)
type User struct {
ID int
Name string
}
func CreateUser(db *sql.DB, name string) (int, error) {
res, err := db.Exec("INSERT INTO users(name) VALUES(?)", name)
if err != nil {
return 0, err
}
id, err := res.LastInsertId()
if err != nil {
return 0, err
}
return int(id), nil
}
func GetUser(db *sql.DB, id int) (User, error) {
var user User
err := db.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(&user.ID, &user.Name)
if err != nil {
return user, err
}
return user, nil
}
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
if err != nil {
log.Fatal(err)
}
}
// main_test.go
package main
import (
"database/sql"
"testing"
_ "github.com/mattn/go-sqlite3"
)
func setupTestDB(t *testing.T) *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatal(err)
}
_, err = db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
if err != nil {
t.Fatal(err)
}
return db
}
func TestCreateAndGetUser(t *testing.T) {
db := setupTestDB(t)
defer db.Close()
// Создание пользователя
userID, err := CreateUser(db, "John Doe")
if err != nil {
t.Fatalf("Failed to create user: %v", err)
}
// Получение пользователя
user, err := GetUser(db, userID)
if err != nil {
t.Fatalf("Failed to get user: %v", err)
}
// Проверка результатов
if user.Name != "John Doe" {
t.Errorf("Expected name to be 'John Doe', got %s", user.Name)
}
}
Интеграционные тесты проверяют, как различные компоненты системы работают вместе. Они помогают выявлять ошибки на границах между модулями и обеспечивают целостность системы. Пишутся аналогично юнит-тестам, но включают взаимодействие между компонентами и часто требуют настройки тестовой среды.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какое ключевое слово в Go используется для создания именованных типов, которые могут быть основой для методов?
Anonymous Quiz
6%
new
59%
type
21%
struct
14%
interface
Что будет, если подставить переменную в массив ?
Спросят с вероятностью 8%
Подстановка переменной в массив происходит путем присвоения значения элементу массива. Они имеют фиксированный размер, который задается при их объявлении, и все элементы массива должны быть одного типа.
Пример использования:
В этом примере:
1️⃣Мы объявляем массив
2️⃣Создаем переменную
3️⃣Подставляем значение переменной
4️⃣Выводим массив, чтобы увидеть результат.
Изменение элементов
Массивы индексируются с нуля, и доступ к элементам массива осуществляется с использованием квадратных скобок
Переменные также могут использоваться для индексов массива:
Массивы могут содержать структуры. Рассмотрим пример с массивом структур:
Подстановка переменной в массив происходит через присваивание значения элементу массива по индексу. Массивы имеют фиксированный размер и могут содержать элементы одного типа. Можно также использовать переменные для индексов массива и работать с массивами структур.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Подстановка переменной в массив происходит путем присвоения значения элементу массива. Они имеют фиксированный размер, который задается при их объявлении, и все элементы массива должны быть одного типа.
Пример использования:
package main
import "fmt"
func main() {
// Объявление и инициализация массива
var arr [5]int
// Переменная, значение которой будет подставлено в массив
value := 10
// Подставляем значение переменной в массив
arr[0] = value
// Вывод массива
fmt.Println(arr) // Output: [10 0 0 0 0]
}
В этом примере:
1️⃣Мы объявляем массив
arr
из 5 целых чисел (int
), изначально инициализированных нулями.2️⃣Создаем переменную
value
и присваиваем ей значение 10.3️⃣Подставляем значение переменной
value
в первый элемент массива arr
с индексом 0.4️⃣Выводим массив, чтобы увидеть результат.
Изменение элементов
Массивы индексируются с нуля, и доступ к элементам массива осуществляется с использованием квадратных скобок
[]
. Можно изменять значения элементов массива, присваивая им новые значения через соответствующие индексы:package main
import "fmt"
func main() {
// Объявление и инициализация массива
arr := [5]int{1, 2, 3, 4, 5}
// Переменные для подстановки
value1 := 10
value2 := 20
// Подстановка значений переменных в массив
arr[1] = value1
arr[3] = value2
// Вывод массива
fmt.Println(arr) // Output: [1 10 3 20 5]
}
Переменные также могут использоваться для индексов массива:
package main
import "fmt"
func main() {
// Объявление и инициализация массива
arr := [5]int{1, 2, 3, 4, 5}
// Переменные для индексов
idx1 := 2
idx2 := 4
// Подстановка значений в массив по индексам
arr[idx1] = 30
arr[idx2] = 50
// Вывод массива
fmt.Println(arr) // Output: [1 2 30 4 50]
}
Массивы могут содержать структуры. Рассмотрим пример с массивом структур:
package main
import "fmt"
// Определение структуры
type Person struct {
Name string
Age int
}
func main() {
// Объявление массива структур
var people [3]Person
// Переменная структуры
p := Person{Name: "Alice", Age: 30}
// Подстановка структуры в массив
people[0] = p
// Прямое присвоение структуры в массив
people[1] = Person{Name: "Bob", Age: 25}
people[2] = Person{Name: "Charlie", Age: 35}
// Вывод массива структур
fmt.Println(people)
// Output: [{Alice 30} {Bob 25} {Charlie 35}]
}
Подстановка переменной в массив происходит через присваивание значения элементу массива по индексу. Массивы имеют фиксированный размер и могут содержать элементы одного типа. Можно также использовать переменные для индексов массива и работать с массивами структур.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
🤔 Какой метод используется для сериализации структуры в JSON формат?
Anonymous Quiz
17%
Unmarshal
5%
Encode
72%
Marshal
6%
Serialize
Стандартный пакет testing предоставляет инструменты для написания и выполнения юнит-тестов. Давайте рассмотрим, как писать юнит-тесты с использованием этого пакета.
_test.go
. Это позволяет инструменту тестирования Go автоматически распознавать их как тестовые файлы.Test
и принимать один аргумент типа *testing.T
. Это соглашение позволяет инструменту тестирования Go идентифицировать их как тестовые функции.package main
func Add(a, b int) int {
return a + b
}
// main_test.go
package main
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5
if result != expected {
t.Errorf("Add(2, 3) = %d; want %d", result, expected)
}
}
Чтобы это сделать, выполните команду
go test
в терминале. Эта команда автоматически найдет и выполнит все тесты в текущем пакете: $ go test Тестирование с таблицей (table-driven tests): Это подход, при котором вы пишете тесты в виде таблицы входных и ожидаемых значений. Это улучшает читаемость и позволяет легко добавлять новые тестовые случаи.
package main
import "testing"
func TestAdd(t *testing.T) {
tests := []struct {
a, b, expected int
}{
{1, 2, 3},
{0, 0, 0},
{-1, -1, -2},
{2, 2, 4},
}
for _, tt := range tests {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
}
}
}
Бенчмаркинг: Для измерения производительности кода используйте функции, начинающиеся с
Benchmark
и принимающие *testing.B
.package main
import "testing"
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}
Примерные тесты (Example Tests)
package main
import "fmt"
func ExampleAdd() {
fmt.Println(Add(2, 3))
// Output: 5
}
TestAdd
для тестирования функции Add
.Запуск тестов
-cover
:$ go test -coverЮнит-тесты пишутся в файлах с суффиксом
_test.go
и выполняются с помощью команды go test
. Они проверяют отдельные функции или методы, чтобы убедиться, что они работают корректно. Пакет testing
предоставляет все необходимые инструменты для написания и выполнения тестов, бенчмарков и примерных тестов.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какое ключевое слово используется для импорта пакета в Go?
Anonymous Quiz
3%
include
2%
require
94%
import
1%
use
Для копирования срезов (slice) можно использовать встроенную функцию
copy
. Эта функция копирует элементы из одного среза в другой, обеспечивая корректное и эффективное копирование данных. Принимает два аргумента: целевой срез и исходный срез. Она копирует элементы из исходного среза в целевой и возвращает количество скопированных элементов. В этом примере исходный срез
src
копируется в целевой срез dst
. Размер целевого среза должен быть равен или больше размера исходного среза, чтобы все элементы могли быть скопированы.package main
import "fmt"
func main() {
// Исходный срез
src := []int{1, 2, 3, 4, 5}
// Целевой срез, который должен иметь достаточно места для копирования элементов
dst := make([]int, len(src))
// Копирование среза
n := copy(dst, src)
// Вывод результатов
fmt.Println("Исходный срез:", src) // Output: Исходный срез: [1 2 3 4 5]
fmt.Println("Целевой срез:", dst) // Output: Целевой срез: [1 2 3 4 5]
fmt.Println("Количество скопированных элементов:", n) // Output: Количество скопированных элементов: 5
}
Частичное копирование: Если целевой срез меньше исходного,
copy
скопирует только столько элементов, сколько поместится в целевой срез.package main
import "fmt"
func main() {
// Исходный срез
src := []int{1, 2, 3, 4, 5}
// Целевой срез меньшего размера
dst := make([]int, 3)
// Копирование среза
n := copy(dst, src)
// Вывод результатов
fmt.Println("Исходный срез:", src) // Output: Исходный срез: [1 2 3 4 5]
fmt.Println("Целевой срез:", dst) // Output: Целевой срез: [1 2 3]
fmt.Println("Количество скопированных элементов:", n) // Output: Количество скопированных элементов: 3
}
Копирование разных типов: Функция
copy
работает только с срезами одного типа. Если вы попытаетесь копировать элементы между срезами разных типов, это приведет к ошибке компиляции.package main
import "fmt"
func main() {
// Исходный срез
src := []int{1, 2, 3, 4, 5}
// Целевой срез
dst := make([]int, 2)
// Копирование части среза
n := copy(dst, src[1:3])
// Вывод результатов
fmt.Println("Исходный срез:", src) // Output: Исходный срез: [1 2 3 4 5]
fmt.Println("Целевой срез:", dst) // Output: Целевой срез: [2 3]
fmt.Println("Количество скопированных элементов:", n) // Output: Количество скопированных элементов: 2
}
Глубокое копирование срезов с вложенными структурами: Если он содержит сложные структуры данных, такие как структуры или срезы с указателями, вам может понадобиться реализовать глубокое копирование, чтобы копировать не только сами элементы, но и данные, на которые они ссылаются.
package main
import "fmt"
type Item struct {
Value int
}
func main() {
// Исходный срез
src := []Item{{1}, {2}, {3}}
// Целевой срез
dst := make([]Item, len(src))
// Глубокое копирование
for i, item := range src {
dst[i] = Item{Value: item.Value}
}
// Изменение исходного среза не влияет на целевой срез
src[0].Value = 100
// Вывод результатов
fmt.Println("Исходный срез:", src) // Output: Исходный срез: [{100} {2} {3}]
fmt.Println("Целевой срез:", dst) // Output: Целевой срез: [{1} {2} {3}]
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой тип используется для представления динамических массивов в Go?
Anonymous Quiz
6%
array
3%
list
86%
slice
6%
map
Моки (mocks) — это объекты, которые имитируют поведение реальных объектов в тестах. Они используются для изоляции тестируемого кода от зависимостей, таких как базы данных, внешние API, файловая система и другие сервисы. Моки позволяют сосредоточиться на тестировании конкретной части кода без необходимости задействовать реальные ресурсы, что делает тесты более быстрыми и предсказуемыми.
Для создания и использования их часто используют специальные библиотеки, такие как
gomock
или testify/mock
. Рассмотрим пример использования библиотеки testify/mock
.Установка библиотеки testify
go get github.com/stretchr/testify
// api.go
package main
type APIClient interface {
FetchData(endpoint string) (string, error)
}
func GetData(client APIClient, endpoint string) (string, error) {
data, err := client.FetchData(endpoint)
if err != nil {
return "", err
}
return data, nil
}
Создадим мок для интерфейса
APIClient
с использованием библиотеки testify/mock
.// api_test.go
package main
import (
"errors"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/assert"
)
// MockAPIClient is a mock type for the APIClient interface
type MockAPIClient struct {
mock.Mock
}
func (m *MockAPIClient) FetchData(endpoint string) (string, error) {
args := m.Called(endpoint)
return args.String(0), args.Error(1)
}
func TestGetData(t *testing.T) {
// Создание мока
mockClient := new(MockAPIClient)
// Настройка мока для возврата данных
mockClient.On("FetchData", "test-endpoint").Return("mocked data", nil)
// Вызов тестируемой функции
data, err := GetData(mockClient, "test-endpoint")
// Проверка результатов
assert.NoError(t, err)
assert.Equal(t, "mocked data", data)
// Проверка вызова мока
mockClient.AssertExpectations(t)
}
func TestGetDataWithError(t *testing.T) {
// Создание мока
mockClient := new(MockAPIClient)
// Настройка мока для возврата ошибки
mockClient.On("FetchData", "error-endpoint").Return("", errors.New("fetch error"))
// Вызов тестируемой функции
data, err := GetData(mockClient, "error-endpoint")
// Проверка результатов
assert.Error(t, err)
assert.Equal(t, "", data)
// Проверка вызова мока
mockClient.AssertExpectations(t)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой пакет используется для работы с регулярными выражениями в Go?
Anonymous Quiz
40%
regex
11%
reg
8%
re
42%
regexp
Оператор квадратные скобки
[]
, применяемый к строке, возвращает байт (тип byte
), представляющий символ в данной позиции строки. Строки являются неизменяемыми последовательностями байтов, и доступ к отдельным символам строки осуществляется через индексацию.package main
import "fmt"
func main() {
str := "hello"
// Получение первого символа строки
firstChar := str[0]
// Вывод значения байта
fmt.Printf("Первый символ: %c\n", firstChar) // Output: Первый символ: h
// Вывод байтового значения
fmt.Printf("Байтовое значение: %d\n", firstChar) // Output: Байтовое значение: 104
}
В этом примере
str[0]
возвращает байт, представляющий первый символ строки "hello"
, который является символом 'h'
и имеет байтовое значение 104.str[i]
возвращает байт, соответствующий i
-тому индексу.[:]
, который также возвращает новую строку.substr := str[1:4]
fmt.Println(substr) // Output: ell
Так как строки в Go являются последовательностями байтов, они могут содержать символы Unicode, которые могут занимать более одного байта. Для правильной обработки Unicode символов нужно использовать пакет
unicode/utf8
.package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "Привет"
// Получение первого символа Unicode
runeValue, size := utf8.DecodeRuneInString(str)
fmt.Printf("Первый символ: %c\n", runeValue) // Output: Первый символ: П
fmt.Printf("Размер в байтах: %d\n", size) // Output: Размер в байтах: 2
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какой метод интерфейса io.Reader используется для чтения данных?
Anonymous Quiz
69%
Read
28%
Scan
3%
Fetch
0%
Receive
Карты (maps) используются для хранения пар ключ-значение. Вставка элементов — это довольно простая операция. Давайте рассмотрим, как это делается, и объясним каждый шаг.
Прежде чем вставить элементы в карту, необходимо ее создать. Карты в Go могут быть созданы с использованием встроенной функции
make
или литерала карты.Создание карты с использованием
make
: Здесь мы создаем карту myMap
, которая использует строки в качестве ключей и целые числа в качестве значений.myMap := make(map[string]int)
Создание карты с использованием литерала карты: В этом примере мы создаем карту и сразу инициализируем ее несколькими значениями.
myMap := map[string]int{
"one": 1,
"two": 2,
}
Вставка элементов в карту: В этом примере мы создаем пустую карту
myMap
и вставляем в нее три пары ключ-значение. Ключи — это строки ("one", "two", "three"), а значения — целые числа (1, 2, 3). Когда мы присваиваем значение конкретному ключу (myMap["one"] = 1
), Go автоматически добавляет эту пару в карту.package main
import "fmt"
func main() {
// Создание карты
myMap := make(map[string]int)
// Вставка элементов
myMap["one"] = 1
myMap["two"] = 2
myMap["three"] = 3
// Вывод карты
fmt.Println(myMap)
}
Обновление элементов карты: Здесь значение ключа "two" обновляется с 2 на 22, а новый ключ "three" добавляется со значением 3.
func main() {
// Создание и инициализация карты
myMap := map[string]int{
"one": 1,
"two": 2,
}
// Обновление значения существующего ключа
myMap["two"] = 22
// Добавление нового ключа
myMap["three"] = 3
// Вывод карты
fmt.Println(myMap)
}
Для проверки, существует ли ключ в карте, используется конструкция с двумя возвращаемыми значениями:
value, exists := myMap["two"]
if exists {
fmt.Println("Key 'two' exists with value:", value)
} else {
fmt.Println("Key 'two' does not exist")
}
Для удаления элемента из карты используется встроенная функция
delete
:delete(myMap, "two")
fmt.Println("After deletion:", myMap)
package main
import "fmt"
func main() {
// Создание карты
myMap := make(map[string]int)
// Вставка элементов
myMap["one"] = 1
myMap["two"] = 2
myMap["three"] = 3
// Обновление элемента
myMap["two"] = 22
// Проверка наличия ключа
value, exists := myMap["two"]
if exists {
fmt.Println("Key 'two' exists with value:", value)
} else {
fmt.Println("Key 'two' does not exist")
}
// Удаление элемента
delete(myMap, "two")
fmt.Println("After deletion:", myMap)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какое значение имеет переменная m["key"] после удаления ключа в Go?
Anonymous Quiz
26%
0
1%
1
58%
nil
15%
panic
Для ключей в картах (maps) можно использовать типы, которые удовлетворяют определенным требованиям. Ключи должны быть сравнимыми, то есть поддерживать операторы сравнения (
==
и !=
). Это означает, что типы, используемые в качестве ключей, должны иметь возможность быть сравнены на равенство. В Go это включает следующие типы:map[int]string
, map[int64]int
map[string]int
map[bool]string
map[*int]string
map[chan int]string
map[interface{}]string
, но конкретные значения, хранимые в интерфейсах, должны быть сравнимы.map[struct{a int; b string}]int
Использование целых чисел в качестве ключей:
package main
import "fmt"
func main() {
intMap := make(map[int]string)
intMap[1] = "one"
intMap[2] = "two"
fmt.Println(intMap) // Output: map[1:one 2:two]
}
Использование строк в качестве ключей:
package main
import "fmt"
func main() {
stringMap := make(map[string]int)
stringMap["one"] = 1
stringMap["two"] = 2
fmt.Println(stringMap) // Output: map[one:1 two:2]
}
Использование структур в качестве ключей:
package main
import "fmt"
type Person struct {
FirstName string
LastName string
}
func main() {
structMap := make(map[Person]int)
structMap[Person{"John", "Doe"}] = 1
structMap[Person{"Jane", "Doe"}] = 2
fmt.Println(structMap) // Output: map[{John Doe}:1 {Jane Doe}:2]
}
Использование указателей в качестве ключей:
package main
import "fmt"
func main() {
int1 := 1
int2 := 2
ptrMap := make(map[*int]string)
ptrMap[&int1] = "one"
ptrMap[&int2] = "two"
fmt.Println(ptrMap) // Output: map[0x...:one 0x...:two]
}
Ограничения
float32
и float64
могут быть использованы, их использование в качестве ключей в картах не рекомендуется из-за проблем с точностью при сравнении плавающих точек.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Какое значение имеет переменная после попытки приведения типа, если приведение не удалось?
Anonymous Quiz
31%
Значение по умолчанию для типа
22%
Ошибка времени выполнения
24%
Значение переменной до приведения
24%
nil