Это матерный язык в мире языков программирования, где простыми выразительными средствами можно сказать больше, чем на родном языке. Плюс gofmt снимает ограничения с выбором редактора.
В мире Go существуют несколько известных "пословиц" или принципов, которые отражают философию языка и его лучшие практики. Вот некоторые из них:
Правило компиляции: "Компилируется всё". Go стремится быть языком с хорошей статической типизацией и строгим компилятором, который помогает выявлять ошибки на этапе компиляции.
Правило эффективности: "Каналы, а не разделяемая память, для общения между горутинами". Go поощряет использование каналов для координации и обмена данными между горутинами, а не общую память, чтобы избежать состояния гонки и других проблем синхронизации.
Правило читаемости: "Код должен быть понятен для людей, а не для машин". Go ставит акцент на читаемость кода и призывает разработчиков писать чистый, понятный и простой код, который легко поддерживать и понимать.
Правило простоты: "Простота лучше сложности". Go стремится к простоте в дизайне языка и стандартной библиотеке, чтобы программистам было легче писать, читать и поддерживать код.
Правило проверки ошибок: "Проверка ошибок обязательна и должна быть явной". Go призывает разработчиков явно проверять ошибки и обрабатывать их, чтобы предотвратить возможные проблемы и улучшить надежность программ.
Правило однозначности: "Чётко выражайте свои намерения". Go ставит акцент на ясное и однозначное выражение намерений в коде, чтобы избежать двусмысленности и улучшить его понимание.
Правило соблюдения стандартов: "Всегда следуйте соглашениям о форматировании кода". Go имеет строгие соглашения о форматировании кода, определенные в стандартной библиотеке, и призывает разработчиков следовать им для повышения согласованности и читаемости кода.
Эти принципы отражают философию Go и помогают разработчикам создавать безопасные, эффективные и понятные программы.
Inversion of Control (IoC) и Dependency Injection (DI) - это два взаимосвязанных принципа, используемые в разработке программного обеспечения для уменьшения связанности и улучшения модульности кода.
IoC - это общий принцип, который говорит о том, что пользовательский код не должен самостоятельно управлять потоком выполнения. Вместо этого поток управления обрабатывается централизованным или внешним сервисом. Это означает, что объекты не создают другие объекты, на которые они полагаются для работы. Вместо этого они получают объекты, которые им нужны, от внешнего источника.
DI - это конкретная форма IoC, где зависимости предоставляются внешним сервисом. DI позволяет нам разрабатывать слабо связанные модули. Внедрение зависимостей осуществляется путем предоставления зависимости объекту (клиенту), а не путем создания зависимости внутри объекта.
Таким образом, можно сказать, что DI - это способ реализации IoC. Они оба работают вместе для достижения слабой связанности и лучшей модульности в коде.
Не путать с Dependency Inversion Principle - это принцип SOLID в объектно-ориентированном программировании, который помогает уменьшить связанность в коде. Он гласит: "Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций".


"Don't communicate by sharing memory, share memory by communicating"
Задача: Реализовать структуру-счетчик, которая будет инкрементироваться в конкурентной среде. По завершению программа должна выводить итоговое значение счетчика.
Условие: Без применения примитивов из пакета sync, исключительно используя канал для обеспечения потокобезопасной передачи/приёма данных.
package main
import (
"context"
"fmt"
"os"
"os/signal"
"sync"
)
type Counter chan int
func NewCounter(ctx context.Context) Counter {
counter := make(Counter)
go func() {
var count int
for {
select {
case v := <-counter:
count += v
case counter <- count:
case <-ctx.Done():
return
}
}
}()
return counter
}
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
counter := NewCounter(ctx)
var wg sync.WaitGroup
const total = 1_000_000
wg.Add(total)
for i := 0; i < total; i++ {
go func() {
counter <- 1
wg.Done()
}()
}
wg.Wait()
fmt.Println(<-counter)
}
ch := make(chan string) - блокирует передатчик, пока не готов приёмникbufferedCh := make(chan string, 1) - неблокирует передатчик, пока не готов приёмникpackage main
import "fmt"
func main() {
ch := make(chan string, 0) // Переключение на буферизированный канал изменит поведение
go func() {
msg := <-ch
fmt.Println("Получено сообщение:", msg)
}()
ch <- "Привет, мир!" // Эта строка блокируется до тех пор, пока горутина не прочитает значение из канала
fmt.Println("Главная горутина завершена")
}
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
done := make(chan bool)
go func() {
for i := range ch {
if i == 20 {
done <- true
return
}
fmt.Printf("%d\n", i)
}
}()
go func() {
for i := 0; i < 10; i++ {
select {
case ch <- i:
time.Sleep(1 * time.Second)
case <-done:
return
}
}
}()
go func() {
for i := 10; i <= 20; i++ {
select {
case ch <- i:
time.Sleep(1 * time.Second)
case <-done:
return
}
}
}()
<-done
}
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
done := make(chan bool)
go func() {
for i := range ch {
fmt.Printf("reader1: %d\n", i)
}
done <- true
}()
go func() {
for i := range ch {
fmt.Printf("reader2: %d\n", i)
}
done <- true
}()
go func() {
for i := range ch {
fmt.Printf("reader3: %d\n", i)
}
done <- true
}()
for i := 0; i <= 300; i++ {
if i == 300 {
close(ch)
return
}
time.Sleep(1 * time.Second)
ch <- i
}
<-done
}
В GoLang не реализованы некоторые особенности объектно-ориентированного программирования, такие как наследование классов и конструкторы. Однако, Go предлагает другие механизмы для достижения тех же целей, например, встраивание структур и интерфейсы.
Инкапсуляция достигается с помощью именованных и неименованных идентификаторов (публичные и приватные). Идентификаторы, начинающиеся с заглавной буквы, являются публичными и могут быть доступными из других пакетов. Идентификаторы, начинающиеся с маленькой буквы, являются приватными и доступны только в пределах своего пакета. Однако, в Go нет строгой приватности, и другие пакеты могут иметь доступ к приватным идентификаторам, если они находятся в том же пакете импорта.
Полиморфизм достигается через интерфейсы. Интерфе
$ claude mcp add yandex \
-- python -m otcore.mcp_server <graph>