appendix FSelf-referential options

 

This appendix presents an alternative options API for the HIT client in chapter 6. We’ll start with our current approach and then move to the self-referential options pattern.

F.1 Struct options

Passing an Options struct directly to SendN has advantages:

  • Simple—Passing an Options value to SendN is straightforward and easy to grasp.
  • Explicit—All options are under a single Options type and are easy to read and maintain.
  • Concise—We declare only an Options struct and some helper functions.

This approach has downsides as well:

  • Defaults—We must pass an empty Options if we want the defaults.
  • Zero-value ambiguity—Unset Options fields do not always mean using the default value. We cannot differentiate between 0 and unset integer fields, for example.

We’ll focus on the downsides of our current approach and then explore an alternative.

F.1.1 Zero-value ambiguity

Suppose that Options had a MaxRetries option:

type Options struct {
    Concurrency int
    MaxRetries int // Defaults to 5 if zero.
}

The zero value of int, 0, makes it hard to distinguish between users who want the default and those who want no retries. Because 0 is ambiguous (it could mean an unset field or no retries), we might add a Boolean field like NoRetries to indicate turning off retries:

type Options struct {
    . . .
    NoRetries bool // NoRetries turns off retries. MaxRetries is ignored.
}

F.1.2 Zero-value options

F.2 Option functions

F.2.1 SendNWith

F.2.2 Options as functions

F.2.3 Applying options