Advanced Techniques
Complex Flag Parsing Strategies
Advanced flag handling goes beyond simple type conversion, involving sophisticated parsing, validation, and configuration management.
Nested and Composite Flag Structures
type ServerConfig struct {
Host string
Port int
Database struct {
URL string
Username string
Password string
}
}
func parseServerConfig() *ServerConfig {
config := &ServerConfig{}
flag.StringVar(&config.Host, "host", "localhost", "Server host")
flag.IntVar(&config.Port, "port", 8080, "Server port")
flag.StringVar(&(&config.Database).URL, "db.url", "", "Database URL")
flag.StringVar(&(&config.Database).Username, "db.username", "", "Database username")
flag.StringVar(&(&config.Database).Password, "db.password", "", "Database password")
flag.Parse()
return config
}
Flag Dependency and Conditional Validation
graph TD
A[Flag Input] --> B{Validate Required Flags}
B --> |Valid| C[Process Flags]
B --> |Invalid| D[Show Error]
D --> E[Exit Program]
Advanced Validation Techniques
Technique |
Description |
Example |
Cross-Flag Validation |
Check relationships between flags |
Ensure port range is valid |
Mutually Exclusive Flags |
Prevent conflicting options |
-v and -q cannot coexist |
Dynamic Flag Generation |
Create flags programmatically |
Plugin-based flag systems |
Environment Variable Integration
func initFlags() {
// Prioritize command-line flags over environment variables
host := os.Getenv("APP_HOST")
if host != "" {
flag.String("host", host, "Server host (overridable by env)")
}
}
Custom Flag Groups and Subcommands
func setupSubcommands() {
serveCmd := flag.NewFlagSet("serve", flag.ExitOnError)
serveHost := serveCmd.String("host", "localhost", "Host for serving")
migrateCmd := flag.NewFlagSet("migrate", flag.ExitOnError)
migrateVersion := migrateCmd.String("version", "latest", "Migration version")
switch os.Args[1] {
case "serve":
serveCmd.Parse(os.Args[2:])
// Serve logic
case "migrate":
migrateCmd.Parse(os.Args[2:])
// Migration logic
}
}
- Lazy Flag Parsing
- Minimal Allocation Strategies
- Efficient Validation Methods
Error Handling and Reporting
type FlagError struct {
Flag string
Message string
}
func (e *FlagError) Error() string {
return fmt.Sprintf("Invalid flag %s: %s", e.Flag, e.Message)
}
Complex Scenario: Configuration Merging
func mergeConfigurations(cliConfig, fileConfig, defaultConfig *Config) *Config {
finalConfig := &Config{}
// Merge with priority: CLI > File > Default
return finalConfig
}
Best Practices
- Design flags for user experience
- Implement comprehensive validation
- Support multiple configuration sources
- Provide clear error messages
At LabEx, we recommend treating flag parsing as a critical design consideration in command-line applications.