💬Что такое стек и как его реализовать с помощью Go?
📌Стек — тип данных, представляющий собой список элементов, организованных по принципу LIFO (last in — first out, «последним пришёл — первым вышел»).
📌Стек хранит последовательность данных. Связаны данные так: каждый элемент указывает на тот, который нужно использовать следующим. Это линейная связь — данные идут друг за другом и нужно брать их по очереди. Из середины стека брать нельзя.
📌Главный принцип работы стека — данные, которые попали в стек недавно, используются первыми. Чем раньше попал — тем позже используется. После использования элемент стека исчезает, и верхним становится следующий элемент.
📌Три основные операции над стеком:
🔸push — добавление элемента
🔸pop — удаление верхнего элемента
🔸peek — возвращение последнего элемента, не удаляя его.
👉 В Go стек можно реализовать с помощью среза:
Мы использовали срез для хранения элементов стека. Метод
📌Стек — тип данных, представляющий собой список элементов, организованных по принципу LIFO (last in — first out, «последним пришёл — первым вышел»).
📌Стек хранит последовательность данных. Связаны данные так: каждый элемент указывает на тот, который нужно использовать следующим. Это линейная связь — данные идут друг за другом и нужно брать их по очереди. Из середины стека брать нельзя.
📌Главный принцип работы стека — данные, которые попали в стек недавно, используются первыми. Чем раньше попал — тем позже используется. После использования элемент стека исчезает, и верхним становится следующий элемент.
📌Три основные операции над стеком:
🔸push — добавление элемента
🔸pop — удаление верхнего элемента
🔸peek — возвращение последнего элемента, не удаляя его.
👉 В Go стек можно реализовать с помощью среза:
type Stack struct {
items []int
}
func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}
func (s *Stack) Pop() int {
if len(s.items) == 0 {
panic("Stack is empty!")
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item
}
func (s *Stack) Peek() int {
if len(s.items) == 0 {
panic("Stack is empty!")
}
return s.items[len(s.items)-1]
}
func (s *Stack) IsEmpty() bool {
return len(s.items) == 0
}
func (s *Stack) Size() int {
return len(s.items)
}
Мы использовали срез для хранения элементов стека. Метод
Push
добавляет элемент на верх стека, метод Pop
извлекает его, а метод Peek
позволяет посмотреть верхний элемент без его извлечения. Также мы использовали проверку стека на наличие элементов.👍11
🧑💻 Статьи для IT: как объяснять и распространять значимые идеи
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
💬Как поменять местами значения двух переменных без временной переменной? Очень простой вопрос, который может быть задан на собесе.
1️⃣Пример с использованием сложения и вычитания:
Таким образом,
2️⃣Пример с использованием XOR (исключающего ИЛИ):
Когда мы применяем XOR дважды с теми же числами, мы получаем исходное значение переменной, что позволяет нам поменять значения без использования временной переменной.
3️⃣Пример с реализацией простой функции
1️⃣Пример с использованием сложения и вычитания:
a := 5
b := 3
a = a + b
// a становится 8b = a - b
// b становится 5 a = a - b
// a становится 3Таким образом,
a
и b
меняются значениями без использования временной переменной.2️⃣Пример с использованием XOR (исключающего ИЛИ):
a := 5
// 0101 в двоичной системеb := 3
// 0011 в двоичной системеa = a ^ b
// a становится 6 (0110)b = a ^ b
// b становится 5 (0101)a = a ^ b
// a становится 3 (0011)Когда мы применяем XOR дважды с теми же числами, мы получаем исходное значение переменной, что позволяет нам поменять значения без использования временной переменной.
3️⃣Пример с реализацией простой функции
func main() {
fmt.Println(swap())
}
func swap() []int {
a, b := 15, 10
b, a = a, b
return []int{a, b}
}
👍14👏3
💬Реализуйте функцию, которая принимает срез целых чисел и переворачивает его без использования временного среза.
📌Простой, но достаточно эффективный способ:
// [1 2 3]
📌Другой способ с использованием рекурсивного метода: рекурсивно меняем местами первый и последний элементы, затем второй и предпоследний и так далее.
// [1 2 3]
📌Простой, но достаточно эффективный способ:
func reverse(sw []int) {
for a, b := 0, len(sw)-1; a < b; a, b = a+1, b-1 {
sw[a], sw[b] = sw[b], sw[a]
}
}
func main() {
x := []int{3, 2, 1}
reverse(x)
fmt.Println(x)
}
// [1 2 3]
📌Другой способ с использованием рекурсивного метода: рекурсивно меняем местами первый и последний элементы, затем второй и предпоследний и так далее.
func reverseRecursive(sw []int, start, end int) {
if start >= end {
return
}
sw[start], sw[end] = sw[end], sw[start]
reverseRecursive(sw, start+1, end-1)
}
func main() {
x := []int{3, 2, 1}
reverseRecursive(x, 0, len(x)-1)
fmt.Println(x)
}
// [1 2 3]
👍4
Самые полезные каналы для программистов в одной подборке!
Сохраняйте себе, чтобы не потерять 💾
🔥Для всех
Библиотека программиста — новости, статьи, досуг, фундаментальные темы
Книги для программистов
IT-мемы
Proglib Academy — тут мы рассказываем про обучение и курсы
🐘PHP
Библиотека пхпшника
Вакансии по PHP, Symfony, Laravel
Библиотека PHP для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по PHP — код, квизы и тесты
🐍Python
Библиотека питониста
Вакансии по питону, Django, Flask
Библиотека Python для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Python — код, квизы и тесты
☕Java
Библиотека джависта — полезные статьи по Java, новости и обучающие материалы
Библиотека Java для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Java — код, квизы и тесты
Вакансии для java-разработчиков
👾Data Science
Библиотека Data Science — полезные статьи, новости и обучающие материалы
Библиотека Data Science для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Data Science — код, квизы и тесты
Вакансии по Data Science, анализу данных, аналитике, искусственному интеллекту
🦫Go
Библиотека Go разработчика — полезные статьи, новости и обучающие материалы по Go
Библиотека Go для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Go — код, квизы и тесты
Вакансии по Go
🧠C++
Библиотека C/C++ разработчика — полезные статьи, новости и обучающие материалы по C++
Библиотека C++ для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по C++ — код, квизы и тесты
Вакансии по C++
💻Другие профильные каналы
Библиотека фронтендера
Библиотека шарписта
Библиотека мобильного разработчика
Библиотека хакера
Библиотека devops’a
Библиотека тестировщика
💼Каналы с вакансиями
Вакансии по фронтенду, джаваскрипт, React, Angular, Vue
Вакансии по C#, .NET, Unity Вакансии по PHP, Symfony, Laravel
Вакансии по DevOps & SRE
Вакансии для мобильных разработчиков
Вакансии по QA тестированию
InfoSec Jobs — вакансии по информационной безопасности
📁Чтобы добавить папку с нашими каналами, нажмите 👉сюда👈
🤖Также у нас есть боты:
Бот с IT-вакансиями
Бот с мероприятиями в сфере IT
Мы в других соцсетях:
🔸VK
🔸YouTube
🔸Дзен
🔸Facebook
🔸Instagram
Сохраняйте себе, чтобы не потерять 💾
🔥Для всех
Библиотека программиста — новости, статьи, досуг, фундаментальные темы
Книги для программистов
IT-мемы
Proglib Academy — тут мы рассказываем про обучение и курсы
🐘PHP
Библиотека пхпшника
Вакансии по PHP, Symfony, Laravel
Библиотека PHP для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по PHP — код, квизы и тесты
🐍Python
Библиотека питониста
Вакансии по питону, Django, Flask
Библиотека Python для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Python — код, квизы и тесты
☕Java
Библиотека джависта — полезные статьи по Java, новости и обучающие материалы
Библиотека Java для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Java — код, квизы и тесты
Вакансии для java-разработчиков
👾Data Science
Библиотека Data Science — полезные статьи, новости и обучающие материалы
Библиотека Data Science для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Data Science — код, квизы и тесты
Вакансии по Data Science, анализу данных, аналитике, искусственному интеллекту
🦫Go
Библиотека Go разработчика — полезные статьи, новости и обучающие материалы по Go
Библиотека Go для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Go — код, квизы и тесты
Вакансии по Go
🧠C++
Библиотека C/C++ разработчика — полезные статьи, новости и обучающие материалы по C++
Библиотека C++ для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по C++ — код, квизы и тесты
Вакансии по C++
💻Другие профильные каналы
Библиотека фронтендера
Библиотека шарписта
Библиотека мобильного разработчика
Библиотека хакера
Библиотека devops’a
Библиотека тестировщика
💼Каналы с вакансиями
Вакансии по фронтенду, джаваскрипт, React, Angular, Vue
Вакансии по C#, .NET, Unity Вакансии по PHP, Symfony, Laravel
Вакансии по DevOps & SRE
Вакансии для мобильных разработчиков
Вакансии по QA тестированию
InfoSec Jobs — вакансии по информационной безопасности
📁Чтобы добавить папку с нашими каналами, нажмите 👉сюда👈
🤖Также у нас есть боты:
Бот с IT-вакансиями
Бот с мероприятиями в сфере IT
Мы в других соцсетях:
🔸VK
🔸YouTube
🔸Дзен
👍1
💬Что из себя представляет пакет cgo и для чего он предназначен?
📌Cgo позволяет создавать пакеты Go, вызывающие код на C. С его помощью мы можем вызывать функции C напрямую из кода на Go и наоборот.
📌Это полезно, когда у нас есть библиотеки на C, которые мы хотим использовать в Go-проекте, или когда нам требуется взаимодействовать с системными вызовами на более низком уровне.
📌Основные особенности cgo:
1. Позволяет встраивать код на C прямо в исходники Go.
2. Автоматически обрабатывает преобразования типов между Go и C.
3. Важно быть осторожным с управлением памятью, так как Go имеет сборщик мусора, а C — нет.
📌Рассмотрим простой пример
• Пакет
• Пакет
• Функция
• Если импорту "C" сразу предшествует комментарий, этот комментарий, называемый преамбулой, используется в качестве заголовка при компиляции частей пакета C. Преамбула может содержать любой код на C, включая объявления и определения функций и переменных. Затем они могут быть переданы из кода Go, как если бы они были определены в пакете "C". Могут использоваться все имена, объявленные в преамбуле, даже если они начинаются со строчной буквы.
👉 Подробнее
📌Cgo позволяет создавать пакеты Go, вызывающие код на C. С его помощью мы можем вызывать функции C напрямую из кода на Go и наоборот.
📌Это полезно, когда у нас есть библиотеки на C, которые мы хотим использовать в Go-проекте, или когда нам требуется взаимодействовать с системными вызовами на более низком уровне.
📌Основные особенности cgo:
1. Позволяет встраивать код на C прямо в исходники Go.
2. Автоматически обрабатывает преобразования типов между Go и C.
3. Важно быть осторожным с управлением памятью, так как Go имеет сборщик мусора, а C — нет.
📌Рассмотрим простой пример
package rand
/*
#include <stdlib.h>
*/
import "C"
func Random() int {
return int(C.random())
}
func Seed(i int) {
C.srandom(C.uint(i))
}
• Пакет
rand
импортирует "C", где "C" — это «псевдопакет», специальное имя, интерпретируемое cgo как ссылка на пространство имен C.• Пакет
rand
содержит четыре ссылки на пакет C: вызовы C.random
и C.srandom
, преобразование C.uint(i)
и оператор импорта. Функция Random
вызывает функцию random
стандартной библиотеки C и возвращает результат. В C функция random
возвращает значение типа C long, которое cgo представляет как тип C.long
. Его нужно преобразовать в тип Go, прежде чем он сможет быть использован кодом Go за пределами этого пакета, используя обычное преобразование типов Go.• Функция
Seed
делает обратное. Она принимает обычный Go int
, преобразует его в тип C unsigned int
и передает его функции C srandom
.• Если импорту "C" сразу предшествует комментарий, этот комментарий, называемый преамбулой, используется в качестве заголовка при компиляции частей пакета C. Преамбула может содержать любой код на C, включая объявления и определения функций и переменных. Затем они могут быть переданы из кода Go, как если бы они были определены в пакете "C". Могут использоваться все имена, объявленные в преамбуле, даже если они начинаются со строчной буквы.
👉 Подробнее
go.dev
C? Go? Cgo! - The Go Programming Language
How to use cgo to let Go packages call C code.
❤6👍5
💬Go — императивный или декларативный? В чем разница между двумя подходами?
📌Go является императивным ЯП. Разница между императивными и декларативными языками программирования заключается в подходе к описанию того, как и что программа должна делать:
1️⃣Императивный подход: в императивных ЯП мы описываем, как решить задачу, шаг за шагом. Мы предоставляем последовательность команд/инструкций для достижения определенного результата.
📌Характерные черты:
• В исходном коде программы записываются инструкции (команды).
• Инструкции должны выполняться последовательно.
• Данные, получаемые при выполнении предыдущих инструкций, могут читаться из памяти последующими инструкциями.
• Данные, полученные при выполнении инструкции, могут записываться в память.
2️⃣ Декларативный подход: в декларативных ЯП мы описываем, что хотим получить, но не указываем конкретные шаги, как это сделать. Вместо этого система или интерпретатор решает, как лучше достичь желаемого результата. Примеры декларативных языков или технологий включают SQL (для запросов к базам данных) и HTML (для описания структуры веб-страниц).
📌Go является императивным ЯП. Разница между императивными и декларативными языками программирования заключается в подходе к описанию того, как и что программа должна делать:
1️⃣Императивный подход: в императивных ЯП мы описываем, как решить задачу, шаг за шагом. Мы предоставляем последовательность команд/инструкций для достижения определенного результата.
📌Характерные черты:
• В исходном коде программы записываются инструкции (команды).
• Инструкции должны выполняться последовательно.
• Данные, получаемые при выполнении предыдущих инструкций, могут читаться из памяти последующими инструкциями.
• Данные, полученные при выполнении инструкции, могут записываться в память.
2️⃣ Декларативный подход: в декларативных ЯП мы описываем, что хотим получить, но не указываем конкретные шаги, как это сделать. Вместо этого система или интерпретатор решает, как лучше достичь желаемого результата. Примеры декларативных языков или технологий включают SQL (для запросов к базам данных) и HTML (для описания структуры веб-страниц).
👍8
💬Каким будет результат при различных операциях (чтение, запись и закрытие) и состояниях канала?
Сегодняшний ответ будет таким👇
Сегодняшний ответ будет таким
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Command.png
375.7 KB
💬Что из себя представляет паттерн «Команда» и как его реализовать на Go?
📌Команда — это поведенческий паттерн, позволяющий заворачивать запросы или простые операции в отдельные объекты.
Это позволяет откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
❗️ В описании паттерна применяются общие понятия, такие как Класс, Объект, Абстрактный класс. Применимо к Go, это Пользовательский Тип, Значение этого Типа и Интерфейс. Также в Go вместо общепринятого наследования используется агрегирование и встраивание.
📌В паттерне Команда мы оперируем следующими понятиями:
• Command — запрос в виде объекта на выполнение
• Receiver — объект-получатель запроса, который будет обрабатывать нашу команду;
• Invoker — объект-инициатор запроса
📌Паттерн отделяет объект, инициирующий операцию, от объекта, который знает, как ее выполнить. Единственное, что должен знать инициатор, это как отправить команду.
📌Для реализации требуется:
1. Базовый абстрактный класс, описывающий интерфейс команды
2. Класс ConcreteCommand, реализующий команду
3. Класс Invoker, реализующий инициатора, записывающий команду и провоцирующий её выполнение
4. Класс Receiver, реализующий получателя и имеющий набор действий, которые команда может запрашивать
📌Invoker умеет складывать команды и инициировать их выполнение по какому-то событию. Обратившись к Invoker, можно отменить команду, пока она не выполнена.
📌ConcreteCommand содержит в себе запросы к Receiver, которые тот должен выполнять. В свою очередь Receiver содержит только набор действий (Actions), которые выполняются при обращении к ним из ConcreteCommand.
📌Команда — это поведенческий паттерн, позволяющий заворачивать запросы или простые операции в отдельные объекты.
Это позволяет откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
📌В паттерне Команда мы оперируем следующими понятиями:
• Command — запрос в виде объекта на выполнение
• Receiver — объект-получатель запроса, который будет обрабатывать нашу команду;
• Invoker — объект-инициатор запроса
📌Паттерн отделяет объект, инициирующий операцию, от объекта, который знает, как ее выполнить. Единственное, что должен знать инициатор, это как отправить команду.
📌Для реализации требуется:
1. Базовый абстрактный класс, описывающий интерфейс команды
2. Класс ConcreteCommand, реализующий команду
3. Класс Invoker, реализующий инициатора, записывающий команду и провоцирующий её выполнение
4. Класс Receiver, реализующий получателя и имеющий набор действий, которые команда может запрашивать
📌Invoker умеет складывать команды и инициировать их выполнение по какому-то событию. Обратившись к Invoker, можно отменить команду, пока она не выполнена.
📌ConcreteCommand содержит в себе запросы к Receiver, которые тот должен выполнять. В свою очередь Receiver содержит только набор действий (Actions), которые выполняются при обращении к ним из ConcreteCommand.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
💬В чем разница между поверхностным и глубоким копированием в Go?
📌Поверхностное копирование (shallow copy) означает создание новой переменной или структуры, которая ссылается на те же данные в памяти, что и исходная переменная/структура.
• Поверхностное копирование применимо, когда мы хотим использовать одни и те же данные, но с разными именами или переменными, и нам не важно, чтобы изменения в одной переменной влияли на другую.
📌Глубокое копирование (deep copy) подразумевает создание новой переменной или структуры, которая имеет собственные, полностью независимые копии данных, содержащихся в исходной переменной или структуре.
• Глубокое копирование может быть важно, например, при работе со сложными структурами данных, где изменение одного элемента может повлиять на целую структуру, а также при сериализации данных или создании копии структуры.
📌Поверхностное копирование (shallow copy) означает создание новой переменной или структуры, которая ссылается на те же данные в памяти, что и исходная переменная/структура.
• Поверхностное копирование применимо, когда мы хотим использовать одни и те же данные, но с разными именами или переменными, и нам не важно, чтобы изменения в одной переменной влияли на другую.
original := []int{1, 2, 3}
copied := original
copied[0] = 99
fmt.Println(original)
// [99 2 3]📌Глубокое копирование (deep copy) подразумевает создание новой переменной или структуры, которая имеет собственные, полностью независимые копии данных, содержащихся в исходной переменной или структуре.
• Глубокое копирование может быть важно, например, при работе со сложными структурами данных, где изменение одного элемента может повлиять на целую структуру, а также при сериализации данных или создании копии структуры.
import "github.com/mohae/deepcopy"
original := []int{1, 2, 3}
copied := deepcopy.Copy(original)
copied[0] = 99
fmt.Println(original)
// [1 2 3]👍9
💬Что из себя представляет middleware в контексте веб-разработки на Go?
📌Middleware представляет собой промежуточные обработчики, которые имеют возможность выполнять код, обрабатывать запросы и ответы в процессе выполнения HTTP-запросов и ответов перед тем, как они достигнут конечных обработчиков.
• Middleware можно использовать для различных целей, таких как аутентификация, авторизация, логирование, обработка ошибок и многое другое.
• В Go, middleware часто реализуется как функции, которые принимают и возвращают значения, соответствующие интерфейсу
• Это позволяет создавать цепочки middleware, которые можно легко комбинировать и повторно использовать в различных частях приложения.
• Например, может существовать middleware для аутентификации пользователей, которое проверяет наличие действительного токена в заголовке HTTP-запроса перед тем, как передать управление следующему обработчику в цепочке. Если токен отсутствует или недействителен, middleware может вернуть ответ с ошибкой, не передавая управление дальше.
• В Go существует несколько популярных библиотек и фреймворков, которые предлагают встроенные или легко интегрируемые решения для создания и управления middleware, такие как Gorilla Mux, Gin или Echo.
📌Подробнее:
👉 Разработка REST-серверов на Go. Часть 5: Middleware
👉 HTTP Middleware
👉 Учимся разрабатывать REST API на Go на примере сокращателя ссылок
📌Middleware представляет собой промежуточные обработчики, которые имеют возможность выполнять код, обрабатывать запросы и ответы в процессе выполнения HTTP-запросов и ответов перед тем, как они достигнут конечных обработчиков.
• Middleware можно использовать для различных целей, таких как аутентификация, авторизация, логирование, обработка ошибок и многое другое.
• В Go, middleware часто реализуется как функции, которые принимают и возвращают значения, соответствующие интерфейсу
http.Handler
или http.HandlerFunc
. • Это позволяет создавать цепочки middleware, которые можно легко комбинировать и повторно использовать в различных частях приложения.
• Например, может существовать middleware для аутентификации пользователей, которое проверяет наличие действительного токена в заголовке HTTP-запроса перед тем, как передать управление следующему обработчику в цепочке. Если токен отсутствует или недействителен, middleware может вернуть ответ с ошибкой, не передавая управление дальше.
• В Go существует несколько популярных библиотек и фреймворков, которые предлагают встроенные или легко интегрируемые решения для создания и управления middleware, такие как Gorilla Mux, Gin или Echo.
📌Подробнее:
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Разработка REST-серверов на Go. Часть 5: Middleware
Это — пятый материал из серии статей , посвящённой разработке REST-серверов на Go. Здесь мы поговорим о middleware. У меня есть материал , посвящённый жизненному циклу HTTP-запросов в серверах,...
👍9
💬Какие операторы есть в языке Go? Назовите основные.
📌Арифметические:
• + : сложение
• - : вычитание
• * : умножение
• / : деление
• % : остаток от деления
• ++ : инкремент
• -- : декремент
📌Сравнительные:
• == : равно
• != : не равно
• < : меньше
• <= : меньше или равно
• > : больше
• >= : больше или равно
📌Логические:
• && : логическое И (AND)
• || : логическое ИЛИ (OR)
• ! : логическое НЕ (NOT)
📌Битовые:
• & : битовое И (AND)
• | : битовое ИЛИ (OR)
• ^ : битовое исключающее ИЛИ (XOR)
• &^ : битовая маска сброса (AND NOT)
• << : левый сдвиг
• >> : правый сдвиг
📌Операторы:
• = : присваивание
• +=, -=, *=, /=, %= : присваивание с операцией
• &=, |=, ^=, <<=, >>=, &^= : битовое присваивание с операцией
📌Прочие:
• & : оператор получения адреса
• * : оператор разыменования указателя
• <- : оператор канала (используется для отправки и получения данных через каналы)
• := : присваивание, используемое для объявления и инициализации переменной
📌Арифметические:
• + : сложение
• - : вычитание
• * : умножение
• / : деление
• % : остаток от деления
• ++ : инкремент
• -- : декремент
📌Сравнительные:
• == : равно
• != : не равно
• < : меньше
• <= : меньше или равно
• > : больше
• >= : больше или равно
📌Логические:
• && : логическое И (AND)
• || : логическое ИЛИ (OR)
• ! : логическое НЕ (NOT)
📌Битовые:
• & : битовое И (AND)
• | : битовое ИЛИ (OR)
• ^ : битовое исключающее ИЛИ (XOR)
• &^ : битовая маска сброса (AND NOT)
• << : левый сдвиг
• >> : правый сдвиг
📌Операторы:
• = : присваивание
• +=, -=, *=, /=, %= : присваивание с операцией
• &=, |=, ^=, <<=, >>=, &^= : битовое присваивание с операцией
📌Прочие:
• & : оператор получения адреса
• * : оператор разыменования указателя
• <- : оператор канала (используется для отправки и получения данных через каналы)
• := : присваивание, используемое для объявления и инициализации переменной
❤10👍5
💬Что из себя представляют Go workspaces?
🔸В версии Go 1.18 был введен новый режим workspace, который позволяет работать с несколькими модулями одновременно без необходимости редактирования
🔸В каждом workspace, модули рассматриваются как основные модули при разрешении зависимостей. До введения этой функции, для добавления функции в один модуль и ее использования в другом модуле, требовалось либо публиковать изменения первого модуля, либо редактировать файл
🔸Режим workspace в Go 1.18 решает ряд проблем, в частности, устраняет необходимость полагаться на локальные замены модулей. Вместо этого, все зависимости контролируются с использованием файла
🔸Файл
🔸Для создания workspace используется команда
📌Основные преимущества:
1. Организация кода: workspaces позволяют группировать связанные модули Go в одном месте, что упрощает управление и организацию кода, особенно в больших проектах с множеством зависимостей и модулей.
2. Управление зависимостями: с помощью workspaces можно легко управлять зависимостями между модулями. Это упрощает обновление, замену или удаление зависимостей в ваших проектах.
3. Локальная разработка: workspaces облегчают локальную разработку, позволяя вам работать над множеством модулей одновременно без необходимости постоянно публиковать изменения в удаленные репозитории.
4. Совместимость с Go модулями: workspaces расширяют возможности Go модулей, добавляя поддержку для работы с несколькими модулями в рамках одного workspace, что делает управление модулями более гибким и удобным.
5. Улучшенный рабочий процесс: Go workspaces предлагают улучшенный рабочий процесс для разработчиков, делая процесс сборки и тестирования более простым и эффективным.
6. Простота и переносимость: создание workspace не требует дополнительных инструментов. Это также обеспечивает переносимость между различными окружениями разработки и командами.
👉 Подробнее
🔸В версии Go 1.18 был введен новый режим workspace, который позволяет работать с несколькими модулями одновременно без необходимости редактирования
go.mod
файлов для каждого модуля. 🔸В каждом workspace, модули рассматриваются как основные модули при разрешении зависимостей. До введения этой функции, для добавления функции в один модуль и ее использования в другом модуле, требовалось либо публиковать изменения первого модуля, либо редактировать файл
go.mod
зависимого модуля с директивой replace
для локальных, неопубликованных изменений модуля.🔸Режим workspace в Go 1.18 решает ряд проблем, в частности, устраняет необходимость полагаться на локальные замены модулей. Вместо этого, все зависимости контролируются с использованием файла
go.work
в корневой директории вашего workspace. 🔸Файл
go.work
содержит директивы use
и replace
, которые переопределяют индивидуальные файлы go.mod
, устраняя необходимость редактирования каждого файла go.mod
вручную.🔸Для создания workspace используется команда
go work init
с перечислением директорий модулей в качестве аргументов, разделенных пробелами. Workspace не обязан содержать модули, с которыми вы работаете. Команда init
создает файл go.work
, который перечисляет модули в workspace. Если вы запустите go work init
без аргументов, команда создаст пустой workspace.📌Основные преимущества:
1. Организация кода: workspaces позволяют группировать связанные модули Go в одном месте, что упрощает управление и организацию кода, особенно в больших проектах с множеством зависимостей и модулей.
2. Управление зависимостями: с помощью workspaces можно легко управлять зависимостями между модулями. Это упрощает обновление, замену или удаление зависимостей в ваших проектах.
3. Локальная разработка: workspaces облегчают локальную разработку, позволяя вам работать над множеством модулей одновременно без необходимости постоянно публиковать изменения в удаленные репозитории.
4. Совместимость с Go модулями: workspaces расширяют возможности Go модулей, добавляя поддержку для работы с несколькими модулями в рамках одного workspace, что делает управление модулями более гибким и удобным.
5. Улучшенный рабочий процесс: Go workspaces предлагают улучшенный рабочий процесс для разработчиков, делая процесс сборки и тестирования более простым и эффективным.
6. Простота и переносимость: создание workspace не требует дополнительных инструментов. Это также обеспечивает переносимость между различными окружениями разработки и командами.
👉 Подробнее
go.dev
Tutorial: Getting started with multi-module workspaces - The Go Programming Language
👍11🔥3🤔1
💬Для чего в программах на Go используются функции?
Функции в Go играют ключевую роль, предлагая способ организации кода, повторного использования логики и разделения задач на меньшие, управляемые компоненты. Они выполняют несколько важных задач:
1️⃣Модульность и организация кода: функции позволяют разбивать программу на меньшие блоки, улучшая читаемость и понимание кода. Это способствует созданию более структурированных и поддерживаемых программ.
2️⃣Повторное использование кода: после написания функции ее можно использовать многократно в разных частях программы или даже в разных программах. Это сокращает дублирование кода и упрощает обновления.
3️⃣Абстракция и инкапсуляция: функции позволяют абстрагироваться от деталей реализации, сосредоточив внимание на функциональности. Это улучшает понимание кода и уменьшает сложность. Кроме того, функции могут создавать границы, предотвращая воздействие изменений в одной части программы на другие.
4️⃣Тестирование: разбиение программы на функции упрощает процесс тестирования. Мы можем тестировать каждую функцию независимо, что делает обнаружение и устранение ошибок более эффективными.
5️⃣Разделение задач: функции позволяют разделять сложные задачи на меньшие подзадачи. Это делает разработку более систематической, позволяя решать проблемы последовательно и шаг за шагом.
Функции в Go играют ключевую роль, предлагая способ организации кода, повторного использования логики и разделения задач на меньшие, управляемые компоненты. Они выполняют несколько важных задач:
1️⃣Модульность и организация кода: функции позволяют разбивать программу на меньшие блоки, улучшая читаемость и понимание кода. Это способствует созданию более структурированных и поддерживаемых программ.
2️⃣Повторное использование кода: после написания функции ее можно использовать многократно в разных частях программы или даже в разных программах. Это сокращает дублирование кода и упрощает обновления.
3️⃣Абстракция и инкапсуляция: функции позволяют абстрагироваться от деталей реализации, сосредоточив внимание на функциональности. Это улучшает понимание кода и уменьшает сложность. Кроме того, функции могут создавать границы, предотвращая воздействие изменений в одной части программы на другие.
4️⃣Тестирование: разбиение программы на функции упрощает процесс тестирования. Мы можем тестировать каждую функцию независимо, что делает обнаружение и устранение ошибок более эффективными.
5️⃣Разделение задач: функции позволяют разделять сложные задачи на меньшие подзадачи. Это делает разработку более систематической, позволяя решать проблемы последовательно и шаг за шагом.
👍11🥱7🤔2
💬Как в Go реализована композиция (агрегация)? Чем она отличается от наследования?
📌В Go композиция достигается путем встраивания одной структуры в другую. Например, встраивание одной структуры в другую позволяет получить доступ к полям встроенной структуры, как если бы они были полями внешней структуры. Композиция в Go более гибкая и рекомендуется как альтернатива наследованию.
📌В нашем примере:
• Определен базовый тип Engine с двумя полями (Power и Type) и методом Start.
• Определен тип Car, в который встраивается Engine.
• В функции main создается экземпляр типа Car, и через этот экземпляр вызывается метод Start встроенного типа Engine, а также обращаются к полям встроенного типа Engine.
📌Таким образом, композиция в Go позволяет объединять простые типы в более сложные структуры, сохраняя при этом простоту и ясность кода.
📌В Go композиция достигается путем встраивания одной структуры в другую. Например, встраивание одной структуры в другую позволяет получить доступ к полям встроенной структуры, как если бы они были полями внешней структуры. Композиция в Go более гибкая и рекомендуется как альтернатива наследованию.
📌В нашем примере:
• Определен базовый тип Engine с двумя полями (Power и Type) и методом Start.
• Определен тип Car, в который встраивается Engine.
• В функции main создается экземпляр типа Car, и через этот экземпляр вызывается метод Start встроенного типа Engine, а также обращаются к полям встроенного типа Engine.
📌Таким образом, композиция в Go позволяет объединять простые типы в более сложные структуры, сохраняя при этом простоту и ясность кода.
👍14🔥3🤔3
🧑💻 Статьи для IT: как объяснять и распространять значимые идеи
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.
Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.
Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.
👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
💬Что будет при чтении/записи из закрытого и неинициализированного канала?
📌Чтение из закрытого канала: когда мы пытаемся читать из закрытого канала, происходит следующее:
1. Если в канале остались значения, которые были в него предварительно записаны, операция чтения будет успешной.
2. Если в канале больше нет значений, операция чтения немедленно завершится, и полученное значение будет нулевым значением для типа данных канала.
3. Если канал уже закрыт и в нем нет значений, попытка прочитать из него снова приведет к получению нулевого значения для типа данных канала.
📌Запись в закрытый канал: попытка записать в закрытый канал вызовет панику. Это означает, что запись в закрытый канал является недопустимой операцией.
📌Чтение из неинициализированного (nil) канала будет заблокировано, как и запись в неициализированный (nil) канал.
☝️Важно отслеживать состояния каналов, инициализировать и закрывать их по мере необходимости, чтобы избежать паник и непредсказуемого поведения.
📌Чтение из закрытого канала: когда мы пытаемся читать из закрытого канала, происходит следующее:
1. Если в канале остались значения, которые были в него предварительно записаны, операция чтения будет успешной.
2. Если в канале больше нет значений, операция чтения немедленно завершится, и полученное значение будет нулевым значением для типа данных канала.
3. Если канал уже закрыт и в нем нет значений, попытка прочитать из него снова приведет к получению нулевого значения для типа данных канала.
ch := make(chan int)
close(ch)
value, ok := <-ch
fmt.Println(value, ok)
// 0 false📌Запись в закрытый канал: попытка записать в закрытый канал вызовет панику. Это означает, что запись в закрытый канал является недопустимой операцией.
ch := make(chan int)
close(ch)
ch <- 42
// panic: send on closed channel📌Чтение из неинициализированного (nil) канала будет заблокировано, как и запись в неициализированный (nil) канал.
☝️Важно отслеживать состояния каналов, инициализировать и закрывать их по мере необходимости, чтобы избежать паник и непредсказуемого поведения.
👍8😁2⚡1
💬Что такое паника (panic) в Go? Какие операции автоматически возвращают панику и останавливают программу?
📌Паники относятся к категории ошибок, которые не ожидались разработчиком. Паника похожа на исключения в других ЯП и предназначена только для ошибок времени выполнения, например:
🔸Доступ к индексу за пределами массива/среза: попытка доступа к элементу массива или среза по индексу за пределами его размера приведет к панике.
🔸Type assertion:
неправильное приведение типа с помощью type assertion может вызвать панику.
🔸Закрытие закрытого канала:
попытка закрыть уже закрытый канал вызовет панику.
📌Обработка паники
Для обработки паники в Go используется конструкция
Если функция
👉 Подробнее
📌Паники относятся к категории ошибок, которые не ожидались разработчиком. Паника похожа на исключения в других ЯП и предназначена только для ошибок времени выполнения, например:
🔸Доступ к индексу за пределами массива/среза: попытка доступа к элементу массива или среза по индексу за пределами его размера приведет к панике.
arr := []int{1, 2, 3}
fmt.Println(arr[5])
// panic: runtime error: index out of range🔸Type assertion:
неправильное приведение типа с помощью type assertion может вызвать панику.
var i interface{} = "hello"
fmt.Println(i.(int))
// panic: interface conversion: interface {} is string, not int🔸Закрытие закрытого канала:
попытка закрыть уже закрытый канал вызовет панику.
ch := make(chan int)
close(ch)
close(ch)
// panic: close of closed channel📌Обработка паники
Для обработки паники в Go используется конструкция
recover
. Recover
возвращает значение, переданное функции panic
, если вызов recover
происходит в той же горутине, что и panic
. Это часто используется в сочетании с defer
, чтобы обеспечить обработку паники и предотвратить завершение всей программы.func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
causePanic()
fmt.Println("This line will not be reached")
}
func causePanic() {
panic("This is a panic")
}
Если функция
causePanic
вызывает панику, функция defer
будет вызвана перед завершением программы. Функция recover
затем используется для захвата значения паники и предотвращения завершения программы.👉 Подробнее
Digitalocean
Обработка паник в Go | DigitalOcean
Ошибки, возникающие в программе, относятся к двум широким категориям: ожидаемые программистом ошибки и ошибки, возникновения которых не ожидалось. Интерфейс …
👍10❤2
💬В чем разница между context.Background() и context.TODO()?
📌Разница между
👉
📌Разница между
context.Background()
и context.TODO()
в основном заключается в их семантическом использовании.👉
context.Background()
используется как стартовый контекст, а context.TODO()
указывает на то, что контекст будет предоставлен позже, другими словами, когда неясно, какой контекст использовать, или он еще недоступен. С точки зрения функциональности они идентичны.🔥13👍2