package main import ( "fmt" "strings" "time" ) type AbstractConfig struct { timeout time.Duration port int32 logLevel string } type Options func(*AbstractConfig) // NewConfig создаёт новый экземпляр AbstractConfig, может принимать опции или возвращает значения по умолчанию. func NewConfig(options ...Options) *AbstractConfig { config := &AbstractConfig{ timeout: time.Second * 5, port: 8080, logLevel: "info", } for _, option := range options { option(config) } return config } // String метод для преобразования AbstractConfig в строку для форматированного вывода. Имплементирует интерфейс Stringer func (cfg *AbstractConfig) String() string { var output strings.Builder output.WriteString(fmt.Sprintf("%-20s%s\n", "timeout", cfg.timeout)) output.WriteString(fmt.Sprintf("%-20s%d\n", "port", cfg.port)) output.WriteString(fmt.Sprintf("%-20s%s\n", "log level", cfg.logLevel)) return output.String() } // WithTimeout устанавливает значение timeout в AbstractConfig func WithTimeout(timeout time.Duration) Options { return func(config *AbstractConfig) { config.timeout = timeout } } // WithPort устанавливает значение port в AbstractConfig func WithPort(port int32) Options { return func(config *AbstractConfig) { config.port = port } } // WithLogLevel устанавливает значение logLevel в AbstractConfig func WithLogLevel(logLevel string) Options { return func(config *AbstractConfig) { config.logLevel = logLevel } } func main() { fmt.Println("Default config") defCfg := NewConfig() fmt.Println(defCfg) fmt.Println("Custom config") customCfg := NewConfig( WithLogLevel("debug"), WithTimeout(10*time.Second), ) fmt.Println(customCfg) }