Go Standard Library: fmt, strings, strconv
The fmt, strings, and strconv packages are fundamental to Go programming. This guide covers their most useful functions and patterns.
fmt Package - Formatting
Print Functions
package main
import "fmt"
func main() {
// Print to stdout
fmt.Print("Hello")
fmt.Print(" ")
fmt.Println("World")
// Printf with format
fmt.Printf("Number: %d, String: %s\n", 42, "hello")
// Sprintf returns string
s := fmt.Sprintf("Value: %v", 42)
fmt.Println(s)
}
Format Verbs
package main
import "fmt"
func main() {
// String and character
fmt.Printf("%s\n", "hello") // hello
fmt.Printf("%q\n", "hello") // "hello" (quoted)
fmt.Printf("%c\n", 65) // A (character)
// Integer
fmt.Printf("%d\n", 42) // 42 (decimal)
fmt.Printf("%x\n", 255) // ff (hexadecimal)
fmt.Printf("%o\n", 8) // 10 (octal)
fmt.Printf("%b\n", 5) // 101 (binary)
// Float
fmt.Printf("%f\n", 3.14) // 3.140000
fmt.Printf("%.2f\n", 3.14159) // 3.14 (2 decimal places)
fmt.Printf("%e\n", 1000.0) // 1.000000e+03 (scientific)
fmt.Printf("%g\n", 1000.0) // 1000 (general format)
// Boolean
fmt.Printf("%v\n", true) // true
fmt.Printf("%t\n", true) // true
// General
fmt.Printf("%v\n", 42) // 42 (value)
fmt.Printf("%T\n", 42) // int (type)
fmt.Printf("%#v\n", []int{1,2}) // []int{1, 2} (Go syntax)
}
Width and Precision
package main
import "fmt"
func main() {
// Width
fmt.Printf("|%5s|\n", "hi") // | hi|
fmt.Printf("|%-5s|\n", "hi") // |hi |
fmt.Printf("|%05d|\n", 42) // |00042|
// Precision
fmt.Printf("%.2f\n", 3.14159) // 3.14
fmt.Printf("%.5s\n", "hello") // hello
// Width and precision
fmt.Printf("%10.2f\n", 3.14159) // " 3.14"
}
Scanning Input
package main
import (
"fmt"
)
func main() {
var name string
var age int
// Scan from stdin
fmt.Print("Enter name: ")
fmt.Scan(&name)
fmt.Print("Enter age: ")
fmt.Scan(&age)
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
strings Package - String Manipulation
Basic Operations
package main
import (
"fmt"
"strings"
)
func main() {
s := "Hello, World!"
// Length
fmt.Println(len(s)) // 13
// Contains
fmt.Println(strings.Contains(s, "World")) // true
// Index
fmt.Println(strings.Index(s, "World")) // 7
fmt.Println(strings.LastIndex(s, "l")) // 10
// Count
fmt.Println(strings.Count(s, "l")) // 3
}
Case Conversion
package main
import (
"fmt"
"strings"
)
func main() {
s := "Hello, World!"
fmt.Println(strings.ToLower(s)) // hello, world!
fmt.Println(strings.ToUpper(s)) // HELLO, WORLD!
fmt.Println(strings.Title(s)) // Hello, World!
}
Trimming
package main
import (
"fmt"
"strings"
)
func main() {
s := " hello world "
fmt.Println(strings.TrimSpace(s)) // hello world
fmt.Println(strings.Trim(s, " ")) // hello world
fmt.Println(strings.TrimPrefix("hello", "he")) // llo
fmt.Println(strings.TrimSuffix("hello", "lo")) // hel
}
Splitting and Joining
package main
import (
"fmt"
"strings"
)
func main() {
// Split
s := "apple,banana,cherry"
parts := strings.Split(s, ",")
fmt.Println(parts) // [apple banana cherry]
// Split with limit
parts2 := strings.SplitN(s, ",", 2)
fmt.Println(parts2) // [apple banana,cherry]
// Fields (split on whitespace)
s2 := "hello world go"
parts3 := strings.Fields(s2)
fmt.Println(parts3) // [hello world go]
// Join
joined := strings.Join(parts, " - ")
fmt.Println(joined) // apple - banana - cherry
}
Replace
package main
import (
"fmt"
"strings"
)
func main() {
s := "hello world hello"
// Replace first n occurrences
fmt.Println(strings.Replace(s, "hello", "hi", 1))
// hi world hello
// Replace all occurrences
fmt.Println(strings.ReplaceAll(s, "hello", "hi"))
// hi world hi
}
String Building
package main
import (
"fmt"
"strings"
)
func main() {
var sb strings.Builder
sb.WriteString("Hello")
sb.WriteString(", ")
sb.WriteString("World")
sb.WriteRune('!')
result := sb.String()
fmt.Println(result) // Hello, World!
}
strconv Package - Type Conversion
String to Integer
package main
import (
"fmt"
"strconv"
)
func main() {
// String to int
i, err := strconv.Atoi("42")
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(i) // 42
// String to int64
i64, err := strconv.ParseInt("42", 10, 64)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(i64) // 42
// String to uint64
u64, err := strconv.ParseUint("42", 10, 64)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(u64) // 42
}
Integer to String
package main
import (
"fmt"
"strconv"
)
func main() {
// Int to string
s := strconv.Itoa(42)
fmt.Println(s) // "42"
// Int64 to string
s2 := strconv.FormatInt(42, 10)
fmt.Println(s2) // "42"
// Different bases
fmt.Println(strconv.FormatInt(255, 16)) // ff (hex)
fmt.Println(strconv.FormatInt(8, 8)) // 10 (octal)
fmt.Println(strconv.FormatInt(5, 2)) // 101 (binary)
}
String to Float
package main
import (
"fmt"
"strconv"
)
func main() {
// String to float64
f, err := strconv.ParseFloat("3.14", 64)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(f) // 3.14
// String to float32
f32, err := strconv.ParseFloat("3.14", 32)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(float32(f32)) // 3.14
}
Float to String
package main
import (
"fmt"
"strconv"
)
func main() {
// Float to string
s := strconv.FormatFloat(3.14, 'f', 2, 64)
fmt.Println(s) // "3.14"
// Different formats
fmt.Println(strconv.FormatFloat(3.14, 'e', 2, 64)) // 3.14e+00
fmt.Println(strconv.FormatFloat(3.14, 'g', 2, 64)) // 3.1
}
String to Boolean
package main
import (
"fmt"
"strconv"
)
func main() {
// String to bool
b, err := strconv.ParseBool("true")
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(b) // true
// Accepted values: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False
b2, _ := strconv.ParseBool("1")
fmt.Println(b2) // true
}
Practical Examples
CSV Parser
package main
import (
"fmt"
"strings"
"strconv"
)
type Record struct {
Name string
Age int
Score float64
}
func parseCSV(line string) *Record {
parts := strings.Split(line, ",")
if len(parts) != 3 {
return nil
}
age, _ := strconv.Atoi(strings.TrimSpace(parts[1]))
score, _ := strconv.ParseFloat(strings.TrimSpace(parts[2]), 64)
return &Record{
Name: strings.TrimSpace(parts[0]),
Age: age,
Score: score,
}
}
func main() {
line := "Alice, 30, 95.5"
record := parseCSV(line)
fmt.Printf("%+v\n", record)
}
Configuration Parser
package main
import (
"fmt"
"strings"
"strconv"
)
type Config struct {
Host string
Port int
Debug bool
Timeout float64
}
func parseConfig(lines []string) *Config {
config := &Config{}
for _, line := range lines {
if strings.HasPrefix(line, "#") {
continue
}
parts := strings.Split(line, "=")
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
switch key {
case "host":
config.Host = value
case "port":
config.Port, _ = strconv.Atoi(value)
case "debug":
config.Debug, _ = strconv.ParseBool(value)
case "timeout":
config.Timeout, _ = strconv.ParseFloat(value, 64)
}
}
return config
}
func main() {
lines := []string{
"# Configuration",
"host=localhost",
"port=8080",
"debug=true",
"timeout=30.5",
}
config := parseConfig(lines)
fmt.Printf("%+v\n", config)
}
Best Practices
โ Good Practices
- Use fmt for formatting - Cleaner than concatenation
- Use strings for manipulation - Optimized functions
- Use strconv for conversion - Type-safe conversion
- Check errors - Handle conversion failures
- Use strings.Builder - For efficient concatenation
- Use raw strings - For regex and paths
- Document format strings - Explain complex formats
- Use appropriate functions - Choose the right tool
โ Anti-Patterns
// โ Bad: String concatenation in loop
var result string
for i := 0; i < 1000; i++ {
result += fmt.Sprintf("Item %d\n", i)
}
// โ
Good: Use strings.Builder
var sb strings.Builder
for i := 0; i < 1000; i++ {
fmt.Fprintf(&sb, "Item %d\n", i)
}
// โ Bad: Ignoring conversion errors
i, _ := strconv.Atoi("not a number")
// โ
Good: Check errors
i, err := strconv.Atoi("42")
if err != nil {
// Handle error
}
Resources and References
Official Documentation
- fmt Package - Formatting
- strings Package - String manipulation
- strconv Package - Type conversion
Recommended Reading
- Effective Go - Best practices
- Go Code Review Comments - Code review guide
- Standard Library Overview - All packages
Tools and Resources
- Go Playground - Online Go editor
- pkg.go.dev - Package documentation
- Go Documentation - Official docs
Summary
Essential standard library packages:
- fmt for formatting and printing
- strings for manipulation
- strconv for type conversion
- Use appropriate functions for each task
- Check errors on conversions
- Use strings.Builder for efficiency
- Leverage the standard library
Master these packages for effective Go programming.
Comments