Карты (maps) предоставляют несколько основных функций и операций для работы с ними. Эти функции позволяют добавлять, удалять, получать значения и проверять наличие ключей в карте.
Для этого используется ключевое слово
map, после которого указываются типы ключей и значений.var myMap map[string]int
Это можно сделать с помощью функции
make или литерала карты.// Инициализация с помощью make
myMap = make(map[string]int)
// Инициализация с помощью литерала карты
myMap = map[string]int{
"Alice": 25,
"Bob": 30,
}
Для этого используется синтаксис индексирования.
myMap["Charlie"] = 35
myMap["Alice"] = 26 // обновление значения по ключу "Alice"
Для этого используется синтаксис индексирования.
age := myMap["Alice"]
fmt.Println(age) // 26
Чтобы проверить это можно использовать двойное присваивание.
age, exists := myMap["David"]
if exists {
fmt.Println("Age of David:", age)
} else {
fmt.Println("David not found")
}
Для этого используется встроенная функция
delete.delete(myMap, "Bob")
Для этого используется цикл
for range.for key, value := range myMap {
fmt.Printf("Key: %s, Value: %d\n", key, value)
}Пример
package main
import (
"fmt"
)
func main() {
// Инициализация карты с помощью литерала
myMap := map[string]int{
"Alice": 25,
"Bob": 30,
}
// Добавление нового элемента
myMap["Charlie"] = 35
// Обновление существующего элемента
myMap["Alice"] = 26
// Извлечение значения по ключу
age := myMap["Alice"]
fmt.Println("Age of Alice:", age) // 26
// Проверка существования ключа
age, exists := myMap["David"]
if exists {
fmt.Println("Age of David:", age)
} else {
fmt.Println("David not found")
}
// Удаление элемента
delete(myMap, "Bob")
// Итерация по карте
for key, value := range myMap {
fmt.Printf("Key: %s, Value: %d\n", key, value)
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Горутины — это легковесные потоки, управляемые рантаймом Go, а не ОС.
Каждая горутина:
- Получает начальный стек размером ~2 КБ.
- Имеет собственные регистры состояния и структуру для планирования.
- Может перераспределять стек по мере роста (growable stack), что экономит ресурсы.
Благодаря этому в Go можно создать десятки или сотни тысяч горутин, в отличие от потоков ОС.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Структуры (struct) представляют собой агрегированные типы данных, которые позволяют объединять несколько различных типов данных под одним именем. Они служат для моделирования объектов и хранения связанных данных, предоставляя удобный способ управления сложными данными.
Определяются с использованием ключевого слова
struct. В структуре могут быть поля различных типов.package main
import "fmt"
// Определение структуры Person
type Person struct {
Name string
Age int
}
func main() {
// Создание экземпляра структуры
var p Person
p.Name = "Alice"
p.Age = 30
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
}
Существует несколько способов инициализации структур.
package main
import "fmt"
// Определение структуры Person
type Person struct {
Name string
Age int
}
func main() {
// Инициализация с использованием литерала структуры
p := Person{Name: "Bob", Age: 25}
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
}
Инициализация по умолчанию
package main
import "fmt"
// Определение структуры Person
type Person struct {
Name string
Age int
}
func main() {
// Инициализация по умолчанию (поля будут нулевыми значениями)
var p Person
fmt.Println("Name:", p.Name) // Пустая строка
fmt.Println("Age:", p.Age) // 0
}
Могут содержать другие структуры в качестве полей, что позволяет моделировать более сложные данные.
package main
import "fmt"
// Определение структур Address и Person
type Address struct {
City string
State string
}
type Person struct {
Name string
Age int
Address Address
}
func main() {
// Инициализация структуры с вложенной структурой
p := Person{
Name: "Charlie",
Age: 40,
Address: Address{
City: "New York",
State: "NY",
},
}
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
fmt.Println("City:", p.Address.City)
fmt.Println("State:", p.Address.State)
}
Могут быть ассоциированы со структурами, что позволяет добавлять функциональность к структурам.
package main
import "fmt"
// Определение структуры Person
type Person struct {
Name string
Age int
}
// Метод для структуры Person
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}
func main() {
p := Person{Name: "David", Age: 35}
p.Greet()
}
Позволяют логически объединять связанные данные в один тип.
Позволяют моделировать реальные объекты и их свойства.
Использование структур делает код более организованным и понятным.
Могут иметь методы, что позволяет добавлять функциональность и поведение объектам.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
B-tree (сбалансированное дерево) организует данные так, чтобы:
- Быстро сужать поиск на каждом уровне.
- Работать эффективно с дисковой памятью (большие блоки и минимум обращений). Линейный перебор проходит все элементы, а B-tree уменьшает количество операций до логарифмического времени — особенно важно при работе с большими объёмами данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
В Go пустой интерфейс
interface{} является особым типом, который может содержать значение любого типа. Это связано с тем, что в Go любой тип реализует пустой интерфейс, поскольку в нем нет методов, которые нужно реализовать. Поскольку пустой интерфейс не требует реализации каких-либо методов, любой тип в Go автоматически реализует этот интерфейс. Это делает пустой интерфейс универсальным контейнером для значений любых типов.
type interface{} interface {}Типа конкретного значения
Самого значения
Когда значение присваивается переменной типа интерфейс, Go сохраняет информацию о типе и значении этого значения. Для пустого интерфейса эта информация может быть любого типа.
Когда значение из пустого интерфейса приводится к конкретному типу, происходит проверка типа во время выполнения. Если значение внутри интерфейса действительно является указанным типом, приведение успешно. В противном случае приведение не удается, и возвращается значение
nil или происходит паника, если приведение выполнено без проверки.Присваивание значений пустому интерфейсу
package main
import "fmt"
func main() {
var i interface{}
i = 42
fmt.Println(i) // 42
i = "hello"
fmt.Println(i) // hello
}
Утверждение типа (Type Assertion)
package main
import "fmt"
func main() {
var i interface{} = "hello"
// Утверждение типа с проверкой
s, ok := i.(string)
if ok {
fmt.Println("String:", s)
} else {
fmt.Println("Not a string")
}
// Утверждение типа без проверки
// Это вызовет панику, если тип не соответствует
s = i.(string)
fmt.Println("String:", s)
}
Использование switch для проверки типа
package main
import "fmt"
func printType(i interface{}) {
switch v := i.(type) {
case string:
fmt.Println("String:", v)
case int:
fmt.Println("Integer:", v)
case bool:
fmt.Println("Boolean:", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}
func main() {
printType("hello")
printType(42)
printType(true)
printType(3.14)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
- Конкурентность (concurrency) — это способность обрабатывать несколько задач одновременно, переключаясь между ними (в т.ч. в одном потоке).
- Параллелизм (parallelism) — это одновременное выполнение задач на нескольких процессорах или ядрах.
Конкурентность — про структуру кода. Параллелизм — про реальное одновременное исполнение.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Go — это императивный язык программирования.
Императивное программирование означает, что программист явно указывает шаги, которые необходимо выполнить для достижения результата. Код в Go представляет собой последовательность команд, изменяющих состояние программы.
package main
import "fmt"
func main() {
sum := 0
for i := 1; i <= 5; i++ {
sum += i // Явно изменяем переменную sum
}
fmt.Println("Сумма:", sum)
}
Хотя Go — это в первую очередь императивный язык, в нем есть элементы декларативного подхода. Например:
map, filter через срезы и функции высшего порядка. интерфейсы позволяют писать код, в котором детали реализации скрыты (инкапсуляция).
вместо явного управления потоками, мы декларируем взаимодействие через каналы.
package main
import "fmt"
func mapSlice(slice []int, f func(int) int) []int {
result := make([]int, len(slice))
for i, v := range slice {
result[i] = f(v) // Декларативное применение функции к элементам
}
return result
}
func main() {
nums := []int{1, 2, 3, 4, 5}
squared := mapSlice(nums, func(n int) int { return n * n })
fmt.Println(squared) // [1 4 9 16 25]
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Если используется первая колонка из индекса — да, индекс может примениться. Если только вторая — скорее всего, нет. В составных индексах важен порядок: индекс может использоваться частично, но только начиная с первой колонки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Нарезка (slicing) — это создание нового слайса, который указывает на подмножество элементов исходного слайса. Этот процесс включает указание начального и конечного индексов для создания нового слайса. Несмотря на свою простоту, slicing имеет несколько нюансов и потенциальных подводных камней, которые важно учитывать.
Синтаксис
newSlice := originalSlice[start:end]
start: начальный индекс (включительно).end: конечный индекс (исключительно).Пример
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := original[1:4] // Элементы с индексами 1, 2 и 3
fmt.Println(newSlice) // [2 3 4]
}
При нарезке слайса важно, чтобы индексы
start и end были в пределах длины исходного слайса. Нарушение этого правила приведет к панике (runtime panic).package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
// Это вызовет панику: runtime error: slice bounds out of range
// newSlice := original[1:6]
// Правильное использование
newSlice := original[1:5]
fmt.Println(newSlice) // [2 3 4 5]
}
Слайсы в Go работают как ссылки на массивы. Это означает, что если вы модифицируете элементы нового слайса, то изменения отразятся и в исходном слайсе.
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := original[1:4]
newSlice[0] = 20
fmt.Println("Original:", original) // [1 20 3 4 5]
fmt.Println("New Slice:", newSlice) // [20 3 4]
}
Длина нового слайса определяется как
end - start. Емкость нового слайса определяется как cap(original) - start.package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := original[1:4]
fmt.Println("New Slice Length:", len(newSlice)) // 3
fmt.Println("New Slice Capacity:", cap(newSlice)) // 4
}
Если нужно создать независимую копию слайса, следует использовать функцию
copy, чтобы изменения в новом слайсе не влияли на исходный.package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := make([]int, 3)
copy(newSlice, original[1:4])
newSlice[0] = 20
fmt.Println("Original:", original) // [1 2 3 4 5]
fmt.Println("New Slice:", newSlice) // [20 3 4]
}
Полная форма нарезки позволяет явно указать емкость нового слайса:
newSlice := original[start:end:max
Это полезно, когда вы хотите контролировать емкость нового слайса.
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := original[1:3:4]
fmt.Println("New Slice:", newSlice) // [2 3]
fmt.Println("New Slice Capacity:", cap(newSlice)) // 3
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3💊1
Дополнительный блок ({ ... }) внутри функции используется для:
- ограничения области видимости переменных;
- создания временной логической области, например, для вложенного вычисления;
- контроля жизни переменной, чтобы освободить её как можно раньше (особенно в длинных функциях или при работе с ресурсами)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это конкретная метрика, используемая для измерения качества обслуживания сервиса. SLI показывает, насколько хорошо сервис соответствует определенным критериям, установленным в SLO (Service Level Objective).
Процент времени, в течение которого сервис доступен для пользователей. Пример: "99.9% времени в течение месяца."
Метрики, такие как время отклика или пропускная способность. Пример: "Среднее время отклика 200 миллисекунд."
Среднее время, необходимое для восстановления сервиса после сбоя. Пример: "Среднее время восстановления 1 час."
Среднее время на принятие мер после обнаружения проблемы. Пример: "Среднее время реакции на инцидент 30 минут."
Процент запросов, завершающихся ошибкой. Пример: "Процент ошибочных запросов не более 0.1%."
"Сервис был доступен 99.95% времени за последний месяц."
"Среднее время отклика сервиса за последний месяц составило 150 миллисекунд."
"Среднее время восстановления сервиса после сбоев за последний месяц составило 45 минут."
"Процент ошибочных запросов за последний месяц составил 0.05%."
Соглашение между поставщиком услуги и клиентом, включающее SLO и описывающее уровень обслуживания, который должен быть достигнут. SLA может включать последствия за невыполнение SLO.
Конкретные цели или метрики, которые определяют уровень обслуживания, которого должен достигнуть сервис. SLO являются частью SLA.
Конкретные метрики, используемые для измерения фактической производительности сервиса относительно установленных SLO. SLI — это количественные показатели, которые служат основой для SLO.
SLI позволяют количественно измерять различные аспекты работы сервиса, такие как доступность и производительность.
SLI используются для постоянного мониторинга сервиса и обеспечения соответствия установленным SLO.
SLI помогают выявлять проблемы в работе сервиса и принимать меры для их устранения.
Анализ SLI позволяет улучшать качество обслуживания путем выявления и устранения узких мест и проблем.
SLI: "99.9% времени сервис доступен."
SLO: "Сервис должен быть доступен не менее 99.9% времени в течение месяца."
SLA: "Если доступность падает ниже 99.9%, клиент получает компенсацию."
SLI: "Среднее время отклика 200 миллисекунд."
SLO: "Среднее время отклика не должно превышать 250 миллисекунд для 95% запросов."
SLA: "Если время отклика превышает 250 миллисекунд, клиент получает компенсацию."
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
В Go функция может возвращать несколько значений одновременно, благодаря множественному возврату.
Ограничений по количеству возвратов формально нет (можно вернуть хоть 10 переменных), но по стилю рекомендуется не перегружать сигнатуру — до 2–3 значений максимум, особенно если не используются именованные возвращаемые значения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Интерфейсы имеют ряд уникальных особенностей и отличий от интерфейсов в других языках программирования, таких как Java, C# или C++.
В Go типы реализуют интерфейсы неявно. Это означает, что если тип имеет методы, определенные в интерфейсе, он автоматически считается реализацией этого интерфейса без явного указания.
package main
import "fmt"
type Stringer interface {
String() string
}
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%s (%d years old)", p.Name, p.Age)
}
func main() {
var s Stringer = Person{Name: "Alice", Age: 30}
fmt.Println(s.String())
}
В Go нет явного наследования интерфейсов или типов. Интерфейсы могут быть составлены из других интерфейсов с помощью композиции, но это не считается наследованием в традиционном смысле.
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}В Go нет методов доступа (getter и setter), как в некоторых других языках. Методы интерфейсов определяются исключительно для реализации логики.
В Go часто используются маленькие и простые интерфейсы с одним или двумя методами. Это позволяет создавать более гибкие и переиспользуемые компоненты.
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}Интерфейсы в Go могут быть составлены из других интерфейсов, что позволяет строить сложные интерфейсы из простых.
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}В Go есть специальный пустой интерфейс
interface{}, который может содержать значение любого типа. Это делает его мощным инструментом для работы с обобщенным кодом.func printValue(v interface{}) {
fmt.Println(v)
}
func main() {
printValue(42)
printValue("hello")
printValue(true)
}Интерфейсы в Java и C# требуют явного указания, какие классы реализуют интерфейсы с использованием ключевого слова
implements. Явное наследование интерфейсов. Методы доступа часто используются. Интерфейсы могут содержать свойства (в C#), которые требуют реализации.Интерфейсы часто реализуются с использованием чисто виртуальных функций. Классы должны явно указывать наследование от интерфейсов. Наследование интерфейсов и классов явно указывается.
Используется динамическая типизация и протоколы, похожие на интерфейсы. Протоколы не требуют явного указания реализации. Python использует утиную типизацию, похожую на неявную реализацию интерфейсов в Go.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Если сервер "тормозит", важно пошагово анализировать:
- CPU / память / диск: проверить загрузку через мониторинг (htop, top, Prometheus, Grafana).
- Сеть: задержки, потери пакетов, перегрузка порта.
- Логи приложения и системы: ошибки, таймауты, исключения.
- Количество запросов / соединений: возможно, сервер не выдерживает нагрузку.
- База данных: медленные запросы, блокировки.
- Очереди / кэши: переполнение, задержки в обработке.
Всё это помогает локализовать «узкое место».
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Prometheus – это мощная система мониторинга с временными рядами (time series), которая собирает метрики из сервисов, хранит их и позволяет строить графики и отправлять алерты.
Pull-модель – сам запрашивает метрики у сервисов (в отличие от push-модели, как в StatsD).
Формат временных рядов – каждая метрика привязана ко времени и меткам (
labels). Язык запросов PromQL – позволяет анализировать и агрегировать метрики.
Автодетектирование сервисов – поддержка Kubernetes, Docker, Consul.
Хранение данных в базе TSDB (Time Series Database).
Гибкая система алертов – интеграция с Alertmanager (уведомления в Slack, Telegram и др.).
Экспортеры/сервисы предоставляют метрики через HTTP-эндпоинт (
/metrics). Prometheus сам запрашивает данные по расписанию.
Метрики хранятся в базе TSDB.
Можно строить графики в Grafana или запрашивать данные через API.
Алерты отправляются в Alertmanager при достижении пороговых значений.
Go-сервис может отдавать метрики через HTTP с помощью prometheus/client_golang
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Создаём метрику
var httpRequests = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
})
func main() {
// Регистрируем метрику
prometheus.MustRegister(httpRequests)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
httpRequests.Inc() // Увеличиваем счётчик при каждом запросе
w.Write([]byte("Hello, Prometheus!"))
})
// Эндпоинт для сбора метрик
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
Пример запроса в PromQL
http_requests_total
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Пустым интерфейсом (interface{}) может быть значение любого типа: числа, строки, структуры или указателя. Это возможно, потому что пустой интерфейс не требует реализации методов, а значит, любая сущность соответствует его требованиям. Например, interface{} часто используется для хранения данных неизвестного типа.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Да, знаком. 12FA (12-Factor App) — это набор принципов, созданных разработчиками Heroku для построения масштабируемых, надежных и удобных в развертывании SaaS-приложений. Эти принципы особенно полезны при разработке облачных сервисов (Cloud-Native).
У приложения должна быть единая кодовая база (один репозиторий), независимо от количества развертываний (production, staging, dev).
Все зависимости должны явно указываться в
go.mod / go.sum (для Go). Никаких глобальных зависимостей в системе. Конфигурация должна храниться в переменных окружения, а не в коде.
export DATABASE_URL="postgres://user:pass@host:5432/db"
Внешние сервисы (БД, кэш, API) должны быть заменяемыми и подключаться через URL (без хардкода).
Сборка, релиз и запуск должны быть разделены. Например, Docker-контейнеры для каждой стадии.
Приложение должно быть бесстатичным (не хранить файлы локально, использовать БД, S3 и т. д.).
Приложение должно быть самодостаточным и слушать порт (например, через
http.ListenAndServe). Масштабируемость должна обеспечиваться горизонтальным масштабированием (разделением на процессы).
Приложение должно быстро запускаться и корректно завершаться (например, ловить SIGTERM).
Среды разработки и продакшена должны быть максимально похожи.
Логи должны писаться в стандартный вывод и обрабатываться внешними системами (ELK, Loki, Grafana).
Скрипты администрирования (миграции, отладка) должны выполняться как отдельные процессы.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4👍1🔥1
Массивы представляют собой фиксированную последовательность элементов одного типа. Являются основополагающей структурой данных, на базе которой строятся более сложные структуры, такие как слайсы. Рассмотрим, как устроены массивы, их особенности, а также сравнение с другими структурами данных.
Размер массива задается при его объявлении и не может изменяться во время выполнения программы.
Все элементы массива имеют один и тот же тип.
В отличие от слайсов, массивы хранят свои элементы в непрерывном блоке памяти.
С указанием типа элементов и фиксированного размера. Это объявление создает массив из пяти целых чисел, инициализированных нулями.
var arr [5]int
Массивы могут быть инициализированы при объявлении
arr := [5]int{1, 2, 3, 4, 5}Можно также инициализировать массив частично, оставив остальные элементы равными нулям:
arr := [5]int{1, 2}Осуществляется с использованием индексов, начиная с 0
fmt.Println(arr[0]) // 1
arr[1] = 10
fmt.Println(arr[1]) // 10
Фиксирована и задается при его объявлении. Ее можно получить с помощью функции
lenfmt.Println(len(arr)) // 5
При присваивании одного массива другому копируются все элементы:
arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := arr1
arr2[0] = 10
fmt.Println(arr1) // [1 2 3 4 5]
fmt.Println(arr2) // [10 2 3 4 5]При этом копируется весь массив:
func modifyArray(a [5]int) {
a[0] = 10
}
arr := [5]int{1, 2, 3, 4, 5}
modifyArray(arr)
fmt.Println(arr) // [1 2 3 4 5]Массивы имеют фиксированный размер, тогда как слайсы динамичны.
Массивы могут быть более производительными для небольших коллекций данных из-за отсутствия накладных расходов на управление динамическими данными.
Использование массивов
package main
import (
"fmt"
)
func main() {
// Объявление и инициализация массива
arr := [5]int{1, 2, 3, 4, 5}
// Доступ к элементам
fmt.Println("First element:", arr[0]) // First element: 1
// Изменение элементов
arr[1] = 10
fmt.Println("Modified array:", arr) // Modified array: [1 10 3 4 5]
// Длина массива
fmt.Println("Length of array:", len(arr)) // Length of array: 5
// Копирование массива
arr2 := arr
arr2[0] = 20
fmt.Println("Original array:", arr) // Original array: [1 10 3 4 5]
fmt.Println("Copied array:", arr2) // Copied array: [20 10 3 4 5]
// Передача массива в функцию
modifyArray(arr)
fmt.Println("Array after modifyArray call:", arr) // Array after modifyArray call: [1 10 3 4 5]
}
func modifyArray(a [5]int) {
a[0] = 10
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4