A method is a function associated with a type through a receiver. In Go, a receiver lets the method validate or operate on data belonging to a value such as Game. Methods can also be exposed to templates when they take no arguments and return one value, or one value plus an error. section 5.1.3 section 11.2.2
Use methods to keep operations focused and maintainable:
- Give one action its own method when a type performs multiple operations; small methods are easier to test and maintain. section 5.1.3
- Attach validation to the relevant type with a receiver, such as validateGuess on Game. section 5.1.3
- Return an error when callers need details about failure; the caller can handle, report, or wrap that error. section 5.1.3
- Call a niladic, exposed method in a template without parentheses, but avoid long chains of field and method calls for clarity. section 11.2.2
Validating a game guess
A Game method can own word-length validation and return nil for a valid guess:\n\nfunc (g *Game) validateGuess(guess []rune) error {\n if len(guess) != solutionLength {\n return fmt.Errorf(\n "expected %d, got %d: %w",\n solutionLength, len(guess), errInvalidWordLength,\n )\n }\n return nil\n}\n\nThe ask method calls g.validateGuess(guess), reports the error when it is non-nil, and continues with the guess otherwise. A table-driven test checks both a nominal word and an overlong word with errors.Is. section 5.1.3
Listing 5.14 game.go: validateGuess method
// errInvalidWordLength is returned when
// the guess has the wrong number of characters.
var errInvalidWordLength = fmt.Errorf("invalid guess, word doesn't have the ➥same number of characters as the solution") #1
// validateGuess ensures the guess is valid enough.
func (g *Game) validateGuess(guess []rune) error {
if len(guess) != solutionLength {
return fmt.Errorf("expected %d, got %d, %w",
solutionLength, len(guess), errInvalidWordLength)
}
return nil
}
Inspect the complete validateGuess method, including its Game receiver, length check, wrapped error, and nil success result. section 5.1.3
