Go语言没有类概念,也没有传统面向对象语言中的构造函数,但我们可以通过普通函数来实现结构体的初始化逻辑。在工程实践中,围绕结构体初始化出现了多种模式,各自适用于不同复杂度的场景。

基础工厂函数模式
最简单的方式是定义一个以 New 为前缀的函数,返回初始化后的结构体或指针。这种方式直观且易于理解。
package main
import "fmt"
type Server struct {
addr string
port int
}
// 简单工厂函数,返回指针
func NewServer(addr string, port int) *Server {
return &Server{
addr: addr,
port: port,
}
}
func main() {
s := NewServer("127.0.0.1", 8080)
fmt.Println(s.addr, s.port)
}
使用配置结构体
当字段较多时,可以把配置抽成一个结构体参数,调用方只需填充关心的字段。
package main
import "fmt"
type Config struct {
Addr string
Port int
TLS bool
}
type Server struct {
cfg Config
}
func NewServer(cfg Config) *Server {
// 设置默认值
if cfg.Addr == "" {
cfg.Addr = "0.0.0.0"
}
if cfg.Port == 0 {
cfg.Port = 80
}
return &Server{cfg: cfg}
}
func main() {
s := NewServer(Config{Addr: "127.0.0.1", Port: 9000})
fmt.Println(s.cfg)
}
函数选项模式
函数选项模式通过传递可变数量的函数来修改结构体,具备良好的扩展性,新增参数不影响旧调用代码。
package main
import "fmt"
type Server struct {
addr string
port int
timeout int
}
type Option func(*Server)
func WithPort(p int) Option {
return func(s *Server) {
s.port = p
}
}
func WithTimeout(t int) Option {
return func(s *Server) {
s.timeout = t
}
}
func NewServer(addr string, opts ...Option) *Server {
s := &Server{
addr: addr,
port: 80,
}
for _, opt := range opts {
opt(s)
}
return s
}
func main() {
s := NewServer("127.0.0.1", WithPort(8080), WithTimeout(30))
fmt.Println(s.addr, s.port, s.timeout)
}
模式对比
| 模式 | 适用场景 | 扩展性 |
|---|---|---|
| 基础工厂函数 | 参数少且稳定 | 低 |
| 配置结构体 | 参数较多 | 中 |
| 函数选项 | 参数易变、需默认值 | 高 |
选择建议
如果结构体字段基本不变,使用基础工厂函数即可;当配置项超过三个且后续可能增加时,建议采用函数选项模式。注意在NewServer这类函数中统一处理默认值,能让调用方更省心。
Go语言的初始化函数本质就是普通函数,重点在于通过命名和参数设计让调用者清楚如何构造可用对象。
Gostructconstructorfunctional_optionsinitialization修改时间:2026-07-24 17:42:34