Конструкторы и фабрики

Вместо них — обычные функции с именем New... или Make...:

type Server struct {
    host    string
    port    int
    timeout time.Duration
}

func NewServer(host string, port int) *Server {
    return &Server{
        host:    host,
        port:    port,
        timeout: 30 * time.Second,
    }
}

Функция-конструктор устанавливает значения по умолчанию и гарантирует корректное начальное состояние.

Для структур с множеством настроек — паттерн functional options:

type Option func(*Server)

func WithTimeout(d time.Duration) Option {
    return func(s *Server) { s.timeout = d }
}

func NewServerWith(host string, port int, opts ...Option) *Server {
    s := &Server{host: host, port: port, timeout: 30 * time.Second}
    for _, o := range opts {
        o(s)
    }
    return s
}

srv := NewServerWith("localhost", 8080,
    WithTimeout(60 * time.Second),
)

Когда один конструктор создаёт разные реализации интерфейса:

type Storage interface{ Save(data []byte) error }

func NewStorage(kind string) Storage {
    switch kind {
    case "s3":
        return &S3Storage{}
    case "disk":
        return &DiskStorage{}
    default:
        return &MemStorage{}
    }
}

ЗаданиеСложность
1Упражнение 1easy
2Упражнение 2medium