Chapter 10: The standard library
The introduction presents Go’s standard library and previews a chapter-long JSON and XML utility built by combining its packages.
After this chapter you will be able to
- Incremental validation utility roadmap. Describe the chapter’s plan to build a JSON and XML validation and conversion utility, adding functionality section by section with standard library packages. Explain that it will use Reader and Writer abstractions, operating-system functions, data parsing and manipulation, and a pipeline through packages to determine data’s form and structure.
- Print and Println output. Distinguish fmt.Print from fmt.Println when displaying text: separate Print calls do not start separate lines, while Println adds a line ending.
- Printf formatting verbs. Explain how fmt.Printf combines a format string with values, such as an application name held in a variable, to control displayed output.
- Sprint string results. Distinguish the Sprint family from the Print family: it builds formatted output but returns a string rather than writing to standard output, so the program can store or use that string elsewhere.
- Typed command-line flags. Explain how to define Boolean, string, or integer flags with functions such as flag.Bool, flag.String, and flag.Int, call flag.Parse(), and then use the parsed values. Describe help and banner flags as examples of optional configuration.
- Positional argument handling. Distinguish optional flags from required positional arguments, and explain that flag.Args() returns the remaining arguments after parsing. Describe checking for required input and output file paths and handling missing ones.
- Reusable Reader and Writer interfaces. Explain how accepting io.Reader for input and io.Writer for output lets the same processing function work with files, operating-system input, screen output, buffers, network connections, or other sources and destinations.
- Composed interfaces and closing responsibility. Explain how Reader, Writer, and Closer combine into interfaces such as ReadCloser and WriteCloser, and why returning a ReadCloser signals that the caller should close the resource.
- Exit status and cleanup. Explain how a CLI communicates success or failure with exit codes, and distinguish os.Exit from returning normally.
- Standard streams as interfaces. Describe the roles of os.Stdin, os.Stdout, and os.Stderr, and explain how io.Reader and io.Writer let the converter use either standard streams or files.
- File access and validation. Distinguish the file-opening functions and describe why the CLI inspects input metadata before processing it.
- Environment based CLI configuration. Explain how environment variables provide runtime configuration alongside flags, and distinguish the os functions for getting, checking, and setting them.
- Encoding package roles. Explain that encoding turns Go values into other representations and back, with specialized subpackages for formats such as JSON, XML, CSV, and base64.
- JSON configuration field mapping. Explain how a Go struct represents the JSON configuration and how JSON field tags map keys to struct fields. State that fields must be exported for encoding/json to access them.
- Standard JSON conversion. Describe how json.Unmarshal reads JSON bytes into a Go value through a pointer and returns an error when parsing or type matching fails. Distinguish this from json.Marshal, which produces JSON bytes from a Go value while respecting struct tags.
- Custom unmarshaling and validation. Explain how an UnmarshalJSON method can validate or transform a value while it is decoded, such as checking that Config.Host is a properly formatted URL. Describe decoding into a temporary anonymous struct before validating and assigning to the receiver, avoiding a recursive call to the same method.
- Shared JSON and XML struct. Explain how JSON and XML struct tags let the same Config type map its fields to JSON keys and XML elements, so either format can be marshalled or unmarshaled.
- Struct-mediated format conversion. Trace conversion from parsing input bytes into the shared Go struct to serializing that struct in the requested output format. Explain that the intermediate struct admits properly structured data and normalizes it during conversion.
- Buffered I/O and interfaces. Explain how bufio builds on io.Reader and io.Writer by holding data in memory and handling it in larger chunks, reducing system calls and improving throughput.
- Buffered reading and format detection. Describe using bufio.Reader for line-by-line reading and Peek to inspect input without consuming it, such as checking whether the first bytes suggest JSON or XML. State that bufio.Scanner offers convenient token-based reading.
- Buffered writing and flushing. Explain how bufio.Writer buffers small writes to an underlying io.Writer and why Flush must be called to ensure remaining output is written, especially when producing converted JSON or XML.
- Basic regex pattern syntax. Explain how literal characters, metacharacters, character classes, and anchors define which strings a regular expression matches.
- Reusable configuration validation patterns. Describe how the configuration validator uses compiled *regexp.Regexp patterns to check field formats, and why Go’s regexp implementation is suitable for that work.
- String inspection for format detection. Explain how checking for substrings, prefixes, and suffixes can help a CLI tool validate input or detect its format, and mention case-insensitive comparison as another examination operation.
- Composable string manipulation functions. Describe how the strings package provides functions for searching, replacing, splitting, joining, and transforming UTF-8 encoded strings, and how basic operations can be combined for input processing or output formatting.
- Numeric input parsing. Explain how strconv helps a CLI tool turn numeric text from arguments or files into typed values, and why parsing errors must be handled when input is invalid.
- Controlled value formatting. Explain how strconv formats typed values as strings with more control than fmt.Sprintf: integer bases and floating-point notation and precision, including the options for FormatFloat.
- CLI tool data flow. Trace how the completed CLI tool takes command-line input through file handling, validation, and JSON/XML conversion to final output, naming the standard-library packages involved.
- Standard library discovery. Explain how to look for standard-library solutions to new Go tasks using pkg.go.dev/std, and when to consider a community package instead.
What it builds on
- Introducing package strings (chapter 2) · Earlier use of a standard library package in a small program
- Calling functions in other packages (chapter 2) · Calling functions from another package.
- Getting program arguments from os.Args (chapter 2) · Earlier use of command-line arguments through os.Args.
- Avoiding a panic by using len (chapter 2) · Checking argument counts to avoid invalid access.
- Files and I/O interfaces (chapter 2) · Introduces files and I/O interfaces.
- Interfaces (chapter 5) · Introduces interfaces as abstractions over implementations.
- Using the os package to interact with the filesystem (chapter 2) · Basic use of the os package to interact with files.
- Structs (chapter 5) · Structs provide the Go representation for the configuration.
Section by section
Introduction
The introduction presents Go’s standard library and previews a chapter-long JSON and XML utility built by combining its packages.
- Standard library and community libraries: Distinguish Go’s standard library, which comes with a Go installation, from community libraries installed afterward, and explain why its breadth is useful for application development.
Why it matters: This distinction helps explain why the chapter can build a useful application using packages already provided with Go. - Incremental validation utility roadmap: Describe the chapter’s plan to build a JSON and XML validation and conversion utility, adding functionality section by section with standard library packages. Explain that it will use Reader and Writer abstractions, operating-system functions, data parsing and manipulation, and a pipeline through packages to determine data’s form and structure.
Why it matters: The utility gives the chapter’s package examples a shared purpose and shows how they work together in an application.
Key terms: standard library, community libraries, JSON, XML, validation and conversion utility, Reader, Writer, standard library packages
10.1 The fmt package
Introduces the fmt package as a way to print CLI output, format and retain strings, and read terminal input.
- Print and Println output: Distinguish fmt.Print from fmt.Println when displaying text: separate Print calls do not start separate lines, while Println adds a line ending.
Why it matters: This distinction prevents a CLI’s output from running together. - Printf formatting verbs: Explain how fmt.Printf combines a format string with values, such as an application name held in a variable, to control displayed output.
Why it matters: Formatting lets the CLI display variable values without manually building every output string. - Sprint string results: Distinguish the Sprint family from the Print family: it builds formatted output but returns a string rather than writing to standard output, so the program can store or use that string elsewhere.
Why it matters: A returned string can be passed on, saved, or used in a custom error message instead of being printed immediately. - Scan family terminal input: Describe how fmt.Scan, fmt.Scanf, and fmt.Scanln read and parse values from standard input for an interactive tool, even though this chapter’s CLI will primarily use files or piped input.
Why it matters: These functions offer a direct way to accept terminal input when a tool needs interaction.
Key terms: fmt.Print, fmt.Println, fmt.Printf, formatting verbs, escape codes, Sprint family, Print family, standard output, fmt.Scan, fmt.Scanf
10.2 The flag package
This section shows how to use Go’s flag package to configure a command-line program and handle required positional arguments.
- Typed command-line flags: Explain how to define Boolean, string, or integer flags with functions such as flag.Bool, flag.String, and flag.Int, call flag.Parse(), and then use the parsed values. Describe help and banner flags as examples of optional configuration.
Why it matters: This is the basic pattern for changing a CLI tool’s behavior without changing its code. - Positional argument handling: Distinguish optional flags from required positional arguments, and explain that flag.Args() returns the remaining arguments after parsing. Describe checking for required input and output file paths and handling missing ones.
Why it matters: A CLI tool needs to separate settings from the filenames or other values it requires to run. - Standard flag package limits: Explain that the standard flag package does not distinguish single-hyphen and double-hyphen flag forms, and that third-party packages such as pflag or cobra offer more advanced features, including aliasing, nested subcommands, and automatic help generation.
Why it matters: Knowing the standard package’s limits helps you choose when a more capable CLI library is warranted.
Key terms: flag package, flag.Bool, flag.String, flag.Int, flag.Parse(), help flag, flag.Args(), positional arguments, input file, output file
10.3 The io package
The section shows how the io package’s small interfaces and stream utilities make I/O code reusable across different sources and destinations.
- Reusable Reader and Writer interfaces: Explain how accepting io.Reader for input and io.Writer for output lets the same processing function work with files, operating-system input, screen output, buffers, network connections, or other sources and destinations.
Why it matters: Code built around these interfaces can change its I/O sources without changing its processing logic. - Formatted output to arbitrary writers: Distinguish fmt.Fprintf from fmt.Printf by explaining that Fprintf directs formatted output to a specified io.Writer rather than always writing to standard output.
Why it matters: Choosing the writer lets formatted messages go to a file, buffer, or connection as readily as to a screen. - Composed interfaces and closing responsibility: Explain how Reader, Writer, and Closer combine into interfaces such as ReadCloser and WriteCloser, and why returning a ReadCloser signals that the caller should close the resource.
Why it matters: The combined interface preserves flexible I/O while making resource ownership clear enough to avoid leaks. - General stream utility functions: Describe how io.ReadAll reads data from a reader, io.Copy transfers data from a Reader to a Writer, io.CopyN copies a specified number of bytes, io.ReadFull fills a requested buffer or reports premature end of stream, and io.LimitReader caps how much can be read.
Why it matters: These utilities handle common whole-stream and size-limited tasks without tying code to a particular source. - Combined and duplicated streams: Describe the purposes of io.MultiReader, io.MultiWriter, io.TeeReader, and io.SectionReader as ways to compose streams, duplicate passing data, or read a section of a larger source.
Why it matters: These helpers let a program build more involved I/O pipelines from simple readers and writers.
Key terms: io.Reader, io.Writer, process function, fmt.Fprintf, fmt.Printf, io.Closer, io.ReadCloser, io.WriteCloser, io.ReaderWriter, io.ReadAll
10.4 The os package
Shows how the os package helps a portable CLI handle exit status, standard streams, files, temporary resources, and environment variables.
- Exit status and cleanup: Explain how a CLI communicates success or failure with exit codes, and distinguish os.Exit from returning normally.
Why it matters: Scripts need a reliable result from the CLI, while the program needs a chance to clean up. - Standard streams as interfaces: Describe the roles of os.Stdin, os.Stdout, and os.Stderr, and explain how io.Reader and io.Writer let the converter use either standard streams or files.
Why it matters: Separating input, output, and diagnostics makes a CLI easier to pipe, redirect, and reuse. - File access and validation: Distinguish the file-opening functions and describe why the CLI inspects input metadata before processing it.
Why it matters: Checking an input before processing helps the CLI avoid unsuitable files and accidental damage. - Temporary resources and safe output: Explain why the CLI uses temporary resources for safer output operations and distinguish individual from recursive cleanup.
Why it matters: Temporary resources and appropriate cleanup reduce the chance of corrupting output or leaving unwanted files behind. - Environment based CLI configuration: Explain how environment variables provide runtime configuration alongside flags, and distinguish the os functions for getting, checking, and setting them.
Why it matters: Environment variables let the same program run with different settings without repeated flags or code changes.
Key terms: os.Exit, exit code, deferred function calls, os.Stdin, os.Stdout, os.Stderr, io.Reader, io.Writer, os.File, os.Open
10.5 The encoding package
Introduces Go’s encoding packages as tools for converting structured data and composing those conversions with I/O, ahead of a JSON and XML tool.
- Encoding package roles: Explain that encoding turns Go values into other representations and back, with specialized subpackages for formats such as JSON, XML, CSV, and base64.
Why it matters: This distinction explains why the JSON and XML examples use different subpackages within the same family. - Encoding and I/O composition: Describe how encoding operations can be combined with Go’s I/O system to read from files, networks, or memory and write results to different destinations.
Why it matters: Composing encoding with I/O lets the same data-processing approach work across different sources and destinations. - JSON and XML tool purpose: Describe the planned tool’s use of encoding packages to parse JSON and XML input, check its structure against Go types, convert between formats, and produce formatted output.
Why it matters: The tool gives a concrete purpose for the JSON and XML processing that follows.
Key terms: serialization, deserialization, BinaryMarshaler, TextMarshaler, encoding/json, encoding/xml, byte slices, io.Reader, io.Writer, data processing pipelines
10.5.1 JSON processing
This section shows how to map server configuration JSON to Go structs, convert values with encoding/json, and customize conversion for validation and redaction.
- JSON configuration field mapping: Explain how a Go struct represents the JSON configuration and how JSON field tags map keys to struct fields. State that fields must be exported for encoding/json to access them.
Why it matters: The field mapping determines which configuration values the JSON package can read and write. - Standard JSON conversion: Describe how json.Unmarshal reads JSON bytes into a Go value through a pointer and returns an error when parsing or type matching fails. Distinguish this from json.Marshal, which produces JSON bytes from a Go value while respecting struct tags.
Why it matters: These two functions provide the basic input and output paths for JSON data. - Custom unmarshaling and validation: Explain how an UnmarshalJSON method can validate or transform a value while it is decoded, such as checking that Config.Host is a properly formatted URL. Describe decoding into a temporary anonymous struct before validating and assigning to the receiver, avoiding a recursive call to the same method.
Why it matters: Custom unmarshaling lets a type enforce rules that ordinary JSON type matching does not express. - Custom marshaling and redaction: Describe how a MarshalJSON method customizes JSON output, including the example of redacting the configuration’s Host value. Explain that implementing the Marshaler interface keeps the type usable with standard JSON processing functions.
Why it matters: Custom output can prevent sensitive values from appearing in logs or transmitted JSON.
Key terms: encoding/json, struct field tags, exported fields, json.Unmarshal, json.Marshal, byte slice, Unmarshaler, UnmarshalJSON, temporary anonymous struct, Host
10.5.2 XML processing
The section shows how one Go struct can support both JSON and XML and serve as the intermediate representation for converting between them.
- Shared JSON and XML struct: Explain how JSON and XML struct tags let the same Config type map its fields to JSON keys and XML elements, so either format can be marshalled or unmarshaled.
Why it matters: A shared type makes conversion possible without maintaining separate data models. - Struct-mediated format conversion: Trace conversion from parsing input bytes into the shared Go struct to serializing that struct in the requested output format. Explain that the intermediate struct admits properly structured data and normalizes it during conversion.
Why it matters: The intermediate struct is what makes bidirectional conversion structured rather than a direct text rewrite. - XML distinctions and conversion output: Describe how XML follows the JSON struct-and-marshal pattern but can also represent attributes, namespaces, mixed content, and more elaborate structures through extended tags and specialized field types. State why the example uses MarshalIndent and distinguishes parsing errors from formatting errors.
Why it matters: These details help make converted configuration files usable and failures easier to diagnose.
Key terms: Config, struct tags, encoding/xml, Marshal, Unmarshal, intermediate Go struct, bidirectional conversion, attributes, namespaces, mixed content
10.6 The bufio package
The section shows how bufio wraps Go’s I/O interfaces to make reading and writing more efficient, and how a JSON/XML converter can use buffered input and output.
- Buffered I/O and interfaces: Explain how bufio builds on io.Reader and io.Writer by holding data in memory and handling it in larger chunks, reducing system calls and improving throughput.
Why it matters: This explains why buffering can help when an application processes files, network data, or streams. - Buffered reading and format detection: Describe using bufio.Reader for line-by-line reading and Peek to inspect input without consuming it, such as checking whether the first bytes suggest JSON or XML. State that bufio.Scanner offers convenient token-based reading.
Why it matters: Looking at input before processing it lets the converter choose a format workflow without relying on a parsing error. - Buffered writing and flushing: Explain how bufio.Writer buffers small writes to an underlying io.Writer and why Flush must be called to ensure remaining output is written, especially when producing converted JSON or XML.
Why it matters: A converter can gain throughput from buffered output only if it also writes out any data still held in memory.
Key terms: bufio, io.Reader, io.Writer, buffering, system calls, bufio.Reader, ReadString, ReadLine, Peek, bufio.Scanner
10.7 The regexp package
This section introduces Go’s regexp package for validating text, explains basic pattern syntax, and gives guidance on performance and maintainability.
- Basic regex pattern syntax: Explain how literal characters, metacharacters, character classes, and anchors define which strings a regular expression matches.
Why it matters: These elements let you describe the format a field must follow. - Greedy and lazy matching: Distinguish greedy repetition from lazy repetition, including how appending ? changes a selector such as * or +.
Why it matters: The choice affects how much text a pattern consumes when more than one match is possible. - Reusable configuration validation patterns: Describe how the configuration validator uses compiled *regexp.Regexp patterns to check field formats, and why Go’s regexp implementation is suitable for that work.
Why it matters: Reusable compiled patterns make repeated field checks practical without recompiling the regex each time. - Regex use and documentation: Justify using regex for sophisticated matching while preferring strings operations for simple checks, and describe how to document a regex that is used.
Why it matters: Choosing the simpler tool and explaining complex patterns makes validation code easier to maintain.
Key terms: regular expression, metacharacters, character classes, anchors, greedy selectors, lazy, *?, +?, regexp package, *regexp.Regexp
10.8 The strings package
This section introduces the strings package as a set of composable functions for manipulating and examining strings, especially when processing input in CLI tools.
- String inspection for format detection: Explain how checking for substrings, prefixes, and suffixes can help a CLI tool validate input or detect its format, and mention case-insensitive comparison as another examination operation.
Why it matters: These checks let a CLI tool make decisions based on the text a user supplies. - Composable string manipulation functions: Describe how the strings package provides functions for searching, replacing, splitting, joining, and transforming UTF-8 encoded strings, and how basic operations can be combined for input processing or output formatting.
Why it matters: Combining small string operations is a practical way to build more involved text-handling logic. - Package functions instead of methods: Distinguish Go’s strings package functions from string methods built into the string type, as the section does when describing Go’s approach to string operations.
Why it matters: This distinction helps you look for string operations in the right place in Go.
Key terms: strings package, substring, prefix, suffix, case-insensitive comparison, input validation, UTF-8 encoded strings, splitting, joining, replacing
10.9 The strconv package
This section shows how to use strconv to parse text into typed values and format values as strings with explicit error handling and control over output.
- Numeric input parsing: Explain how strconv helps a CLI tool turn numeric text from arguments or files into typed values, and why parsing errors must be handled when input is invalid.
Why it matters: A CLI tool needs to reject malformed input rather than process it as a valid number. - Boolean configuration parsing: Describe how ParseBool converts string configuration values to Booleans, including its accepted true and false spellings and its error for other values.
Why it matters: Configuration values often arrive as text even when the program needs a Boolean. - Controlled value formatting: Explain how strconv formats typed values as strings with more control than fmt.Sprintf: integer bases and floating-point notation and precision, including the options for FormatFloat.
Why it matters: Explicit formatting produces predictable output for displays and logs.
Key terms: strconv, parsing, typed values, error handling, ParseBool, Boolean, fmt.Sprintf, FormatFloat, numeric base, format
10.10 Scratching the surface
This section recaps the completed JSON/XML CLI tool and encourages readers to look for standard-library solutions before turning to community packages.
- CLI tool data flow: Trace how the completed CLI tool takes command-line input through file handling, validation, and JSON/XML conversion to final output, naming the standard-library packages involved.
Why it matters: Seeing how the packages work together makes the completed tool easier to understand and adapt. - Standard library discovery: Explain how to look for standard-library solutions to new Go tasks using pkg.go.dev/std, and when to consider a community package instead.
Why it matters: Checking the standard library first can reveal a documented solution without adding an outside package.
Key terms: flag, os, io, encoding/json, encoding/xml, regexp, Go standard library, pkg.go.dev/std, community package
10.11 Summary
The section recaps standard-library packages for command-line programs, I/O, structured-data encoding, and text processing.
Where this is used later
- Packages (chapter 11) · Provides context for considering packages beyond the standard library.
Concepts explained in this chapter
- struct tagA struct tag is metadata attached to a Go struct field that can guide reflection-based processing such as serialization and field mapping.
- os packageThe os package is a Go standard-library package that provides platform-independent interfaces for operating-system functionality, including files, processes, and environment variables.
- serializationMarshaling is the process of converting an in-memory value into a serialized representation.
- deserializationUnmarshaling is the process of reconstructing an in-memory value from a serialized representation.
- encoding/jsonencoding/json is Go's standard-library package for encoding Go values as JSON and decoding JSON into Go values.
- io.Readerio.Reader is the Go interface for reading a stream of bytes into a supplied buffer.
- io.Writerio.Writer is the Go interface for writing byte data to a destination.
- ioio is the Go standard-library package that defines interfaces and utilities for input and output operations.
- validationValidation is the process of checking that input data satisfies required structural, type, and semantic constraints.
- MarshalJSONMarshalJSON is a method convention that customizes how a Go value is encoded as JSON.
- UnmarshalJSONUnmarshalJSON is a method convention that customizes how JSON data is decoded into a Go value.
- json.Marshaljson.Marshal is a Go standard-library function that encodes a Go value as a JSON-formatted byte sequence.
- json.Unmarshaljson.Unmarshal is a Go standard-library function that decodes JSON data into a supplied Go value.
- fmtThe fmt package is a Go standard-library package that provides formatted input and output operations.
- encoding/xmlencoding/xml is a Go standard-library package for encoding and decoding XML documents.
- bufiobufio is Go's standard library package for buffered input and output, including scanner-based tokenization.
- command-line argumentA command-line argument is a value supplied to a program when it is invoked from a command line or operating-system process launcher.
- strconvstrconv is a Go standard-library package for converting between strings and basic data types such as integers, floating-point numbers, and booleans.
- regexp packageThe regexp package is Go's standard-library package for compiling and matching regular expressions.
- bufferingBuffering is the technique of temporarily accumulating input or output data in memory to reduce the cost of individual transfers.
- flag packageThe flag package is a Go standard-library package for defining, parsing, and retrieving command-line options and positional arguments.
- ReadCloserReadCloser is a Go interface combining the ability to read data with the ability to close a resource.
- fmt.Fprintffmt.Fprintf is a Go standard-library function that formats text according to a format string and writes it to an io.Writer.
- io.Copyio.Copy transfers data from a Reader to a Writer until the input reaches end of file or an error occurs.
- fmt.Printlnfmt.Println is a Go standard-library function that prints its arguments with spaces between them and a trailing newline.
- format verbA format verb is a formatting directive that specifies how a value is converted to text in formatted output.
- packageA package is a Go compilation and namespace unit that groups related declarations and controls their visibility across source files.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
