在 golang 中是不支持默认参数的,micro 中有一种优雅的实现方法(并非 micro 首创),叫做 Functional Options Patter。Functional Options 可以用来实现简洁的支持默认参数的函数方法。

options

package server

import (
	"time"
)

type Options struct {
	ConnectTimeOut time.Duration
	Name           string
	Address        string
}

type Option func(*Options)

func newOptions(opt ...Option) Options {
	opts := Options{}

	for _, o := range opt {
		o(&opts)
	}

	if len(opts.Address) == 0 {
		opts.Address = DefaultAddress
	}

	if len(opts.Name) == 0 {
		opts.Name = DefaultName
	}

	if opts.ConnectTimeOut == time.Duration(0) {
		opts.ConnectTimeOut = DefaultConnectTimeOut
	}

	return opts
}

// Name server name
func Name(n string) Option {
	return func(o *Options) {
		o.Name = n
	}
}

// Address server address
func Address(a string) Option {
	return func(o *Options) {
		o.Address = a
	}
}

// ConnectTimeOut 连接超时时间
func ConnectTimeOut(t time.Duration) Option {
	return func(o *Options) {
		o.ConnectTimeOut = t
	}
}

server

package server

import "sync"

var (
	DefaultAddress        = ":0"
	DefaultName           = "server"
	DefaultConnectTimeOut = time.Second * 4
)

type Server struct {
	sync.RWMutex
	opts Options
}

func NewServer(opts ...Option) Server {
	options := newOptions(opts...)
	return &Server{
		opts: options,
	}
}

func (s *Server) Options() Options {
	s.RLock()
	opts := s.opts
	s.RUnlock()
	return opts
}

func (s *Server) Init(opts ...Option) error {
	s.Lock()
	for _, opt := range opts {
		opt(&s.opts)
	}
	s.Unlock()
	return nil
}

func (s *Server) Start() error {
	return nil
}

func (s *Server) Stop() error {
	return nil
}

使用

server := NewServer(
	Name("test Name"),
	Address("test Address"),
)