当前位置: 首页 > 工具软件 > micro-auth > 使用案例 >

Options的理解和在go-micro中的使用

翟英达
2023-12-01

Options的理解和在go-micro中的使用

c++中有重载,python中的函数参数可以省略,golang提供Options达到替代效果,几乎很多的框架中都有应用。

一般框架中似乎会定义一个叫做Options的结构体,感觉这个命名对初学者真不友好。记住Option是函数,Options是结构体。Options里面包含该框架的基本类型,而Option则代表操作其中一个或多个类型的函数。

type Option func(*Options)

感觉不叫Options反而更加易读。如Person结构体

type Person struct {
 Name string
 Age int
 Gender int
 Height int

 Country string
 City    string
}

type Option func(*Person) //Option是对Person结构体操作的函数的别名

func NewPerson(opt ...Option) *Person{
 p := new(Person)
 p.Country = "china"
 p.City = "beijing"
 //上面提供默认值
 for _, o := range opt{
     o(p)
 }
 return p
}
func WithRegional(country, city string) Options {
 return func(p *Person){
     p.Country = country
     p.City = city
 }
}


person2 := NewPerson(WithPersonProperty("dongxiaojian", 18, 1, 180)
,WithRegional("china", "hebei"))

go-micrio中的例子,它的主要用到的类型/组件都封装在了Options中

type Options struct {
	Auth      auth.Auth
	Broker    broker.Broker
	Cmd       cmd.Cmd
	Config    config.Config
	Client    client.Client
	Server    server.Server
	Store     store.Store
	Registry  registry.Registry
	Runtime   runtime.Runtime
	Transport transport.Transport
	Profile   profile.Profile

	// Before and After funcs
	BeforeStart []func() error
	BeforeStop  []func() error
	AfterStart  []func() error
	AfterStop   []func() error

	// Other options for implementations of the interface
	// can be stored in a context
	Context context.Context

	Signal bool
}

Service是interface的类型,Options()接口返回Options结构体(迷惑命名)

type Service interface {
	// The service name
	Name() string
	// Init initialises options
	Init(...Option)
	// Options returns the current options
	Options() Options
	// Client is used to call services
	Client() client.Client
	// Server is for handling requests and events
	Server() server.Server
	// Run the service
	Run() error
	// The service implementation
	String() string
}

对一个微服务Service初始化,要初始化其中的Options结构体

// NewService creates and returns a new Service based on the packages within.
func NewService(opts ...Option) Service {
	return newService(opts...)
}
func newService(opts ...Option) Service {
//  .....
	options := newOptions(opts...)
//省略其他代码
}

func newOptions(opts ...Option) Options {
	opt := Options{
		Auth:      auth.DefaultAuth,
		Broker:    broker.DefaultBroker,
		Cmd:       cmd.DefaultCmd,
		Config:    config.DefaultConfig,
		Client:    client.DefaultClient,
		Server:    server.DefaultServer,
		Store:     store.DefaultStore,
		Registry:  registry.DefaultRegistry,
		Runtime:   runtime.DefaultRuntime,
		Transport: transport.DefaultTransport,
		Context:   context.Background(),
		Signal:    true,
	}

//遍历Option函数来对Options结构体的opt对象初始化(迷惑的命名)
	for _, o := range opts {
		o(&opt)
	}

	return opt
}

比如我想用一个特定的Registry注册中心来初始化Options结构体,Registry函数是初始化操作Options结构体的函数之一,返回的是Option也就是函数

// Registry sets the registry for the service
// and the underlying components
func Registry(r registry.Registry) Option {
	return func(o *Options) {
		o.Registry = r
		// Update Client and Server
		o.Client.Init(client.Registry(r))
		o.Server.Init(server.Registry(r))
		// Update Broker
		o.Broker.Init(broker.Registry(r))
	}
}


//
	service := micro.NewService(
		//添加consul 作为注册中心
		micro.Registry(consulRegistry),

	)


 类似资料: