Telegram Group & Telegram Channel
Анти-функциональные опции в Go

Часто в Go можно встретить такую конструкцию:


type Options struct {
Timeout time.Duration
Retries int
Logger *log.Logger
}

func DoSomething(ctx context.Context, opts Options) error {
if opts.Timeout == 0 {
opts.Timeout = 5 * time.Second
}
if opts.Retries == 0 {
opts.Retries = 3
}
if opts.Logger == nil {
opts.Logger = log.Default()
}

// дальше используем opts
}


На первый взгляд — удобно. Но на практике это ведёт к скрытым багам и неочевидному поведению. Почему?

🔸 Проблема 1: нулевое значение может быть валидным

Допустим, я хочу отключить ретраи и передаю Retries: 0. Но функция решает, что "ноль — это дефолт", и перезаписывает его на 3. В итоге получается поведение, которого явно не хотел.

🔸 Проблема 2: смешение ответственности

Функция DoSomething теперь делает больше, чем нужно: она и бизнес-логику выполняет, и значения инициализирует. Это противоречит принципу единственной ответственности и усложняет тестирование.

🔸 Проблема 3: дублирование

Если в коде много таких функций, каждая будет по-своему инициализировать Options. Это ведёт к дублированию и рассыпанной логике дефолтов.


💡 Что делать?

Вынеси дефолтные значения в отдельную функцию:


func DefaultOptions() Options {
return Options{
Timeout: 5 * time.Second,
Retries: 3,
Logger: log.Default(),
}
}


Теперь клиентский код выглядит явно:


opts := DefaultOptions()
opts.Retries = 0 // без ретраев

DoSomething(ctx, opts)


https://rednafi.com/go/dysfunctional_options_pattern/

👉 @golang_lib



tg-me.com/golang_lib/492
Create:
Last Update:

Анти-функциональные опции в Go

Часто в Go можно встретить такую конструкцию:


type Options struct {
Timeout time.Duration
Retries int
Logger *log.Logger
}

func DoSomething(ctx context.Context, opts Options) error {
if opts.Timeout == 0 {
opts.Timeout = 5 * time.Second
}
if opts.Retries == 0 {
opts.Retries = 3
}
if opts.Logger == nil {
opts.Logger = log.Default()
}

// дальше используем opts
}


На первый взгляд — удобно. Но на практике это ведёт к скрытым багам и неочевидному поведению. Почему?

🔸 Проблема 1: нулевое значение может быть валидным

Допустим, я хочу отключить ретраи и передаю Retries: 0. Но функция решает, что "ноль — это дефолт", и перезаписывает его на 3. В итоге получается поведение, которого явно не хотел.

🔸 Проблема 2: смешение ответственности

Функция DoSomething теперь делает больше, чем нужно: она и бизнес-логику выполняет, и значения инициализирует. Это противоречит принципу единственной ответственности и усложняет тестирование.

🔸 Проблема 3: дублирование

Если в коде много таких функций, каждая будет по-своему инициализировать Options. Это ведёт к дублированию и рассыпанной логике дефолтов.


💡 Что делать?

Вынеси дефолтные значения в отдельную функцию:


func DefaultOptions() Options {
return Options{
Timeout: 5 * time.Second,
Retries: 3,
Logger: log.Default(),
}
}


Теперь клиентский код выглядит явно:


opts := DefaultOptions()
opts.Retries = 0 // без ретраев

DoSomething(ctx, opts)


https://rednafi.com/go/dysfunctional_options_pattern/

👉 @golang_lib

BY Библиотека Go (Golang) разработчика




Share with your friend now:
tg-me.com/golang_lib/492

View MORE
Open in Telegram


telegram Telegram | DID YOU KNOW?

Date: |

For some time, Mr. Durov and a few dozen staffers had no fixed headquarters, but rather traveled the world, setting up shop in one city after another, he told the Journal in 2016. The company now has its operational base in Dubai, though it says it doesn’t keep servers there.Mr. Durov maintains a yearslong friendship from his VK days with actor and tech investor Jared Leto, with whom he shares an ascetic lifestyle that eschews meat and alcohol.

A Telegram spokesman declined to comment on the bond issue or the amount of the debt the company has due. The spokesman said Telegram’s equipment and bandwidth costs are growing because it has consistently posted more than 40% year-to-year growth in users.

telegram from de


Telegram Библиотека Go (Golang) разработчика
FROM USA