• 功能选项

    功能选项

    功能选项是一种模式,声明一个不透明 Option 类型,该类型记录某些内部结构体的信息。您的函数接受这些不定数量的选项参数,并将选项参数上的信息作用于内部结构上。

    此模式可用于扩展构造函数和实现其他公共 API 中的可选参数,特别是这些参数已经有三个或者超过三个的情况下。

    BadGood
    1. // package db
    2. func Connect(
    3. addr string,
    4. timeout time.Duration,
    5. caching bool,
    6. ) (Connection, error) {
    7. // …
    8. }
    9. // Timeout and caching must always be provided,
    10. // even if the user wants to use the default.
    11. db.Connect(addr, db.DefaultTimeout, db.DefaultCaching)
    12. db.Connect(addr, newTimeout, db.DefaultCaching)
    13. db.Connect(addr, db.DefaultTimeout, false / caching /)
    14. db.Connect(addr, newTimeout, false / caching /)
    1. type options struct {
    2. timeout time.Duration
    3. caching bool
    4. }
    5. // Option overrides behavior of Connect.
    6. type Option interface {
    7. apply(options)
    8. }
    9. type optionFunc func(options)
    10. func (f optionFunc) apply(o options) {
    11. f(o)
    12. }
    13. func WithTimeout(t time.Duration) Option {
    14. return optionFunc(func(o options) {
    15. o.timeout = t
    16. })
    17. }
    18. func WithCaching(cache bool) Option {
    19. return optionFunc(func(o options) {
    20. o.caching = cache
    21. })
    22. }
    23. // Connect creates a connection.
    24. func Connect(
    25. addr string,
    26. opts Option,
    27. ) (*Connection, error) {
    28. options := options{
    29. timeout: defaultTimeout,
    30. caching: defaultCaching,
    31. }
    32. for _, o := range opts {
    33. o.apply(&options)
    34. }
    35. // …
    36. }
    37. // Options must be provided only if needed.
    38. db.Connect(addr)
    39. db.Connect(addr, db.WithTimeout(newTimeout))
    40. db.Connect(addr, db.WithCaching(false))
    41. db.Connect(
    42. addr,
    43. db.WithCaching(false),
    44. db.WithTimeout(newTimeout),
    45. )

    另见,

    • Self-referential functions and the design of options
    • Functional options for friendly APIs