Функция flag.Var
Функция flag.Var позволяет связать пользовательский тип данных с флагом командной строки. Первым параметром она принимает значение, реализующее интерфейс flag.Value, вторым - имя флага в виде строки, третьим - значение по умолчанию в виде строки, четвертым - описание флага. Функция используется когда стандартные типы флагов не подходят для решения задачи.
Синтаксис
flag.Var(value flag.Value, name string, defaultValue string, usage string)
Интерфейс flag.Value
Для работы с flag.Var необходимо реализовать интерфейс flag.Value, который содержит два метода:
type Value interface {
String() string
Set(string) error
}
Метод String возвращает строковое представление значения флага, а метод Set устанавливает новое значение из строки и возвращает ошибку в случае некорректных данных.
Пример
Давайте создадим флаг для работы с цветами в формате RGB:
package main
import (
"flag"
"fmt"
"strconv"
"strings"
)
type Color struct {
R, G, B int
}
func (c *Color) String() string {
return fmt.Sprintf("RGB(%d,%d,%d)", c.R, c.G, c.B)
}
func (c *Color) Set(value string) error {
parts := strings.Split(value, ",")
if len(parts) != 3 {
return fmt.Errorf("invalid color format, expected R,G,B")
}
r, err := strconv.Atoi(parts[0])
if err != nil {
return err
}
g, err := strconv.Atoi(parts[1])
if err != nil {
return err
}
b, err := strconv.Atoi(parts[2])
if err != nil {
return err
}
c.R, c.G, c.B = r, g, b
return nil
}
func main() {
var color Color
flag.Var(&color, "color", "255,0,0", "RGB color values separated by commas")
flag.Parse()
fmt.Printf("Selected color: %s\n", color.String())
}
Запустим программу с различными параметрами:
$ go run main.go -color 255,0,0
"Selected color: RGB(255,0,0)"
$ go run main.go -color 0,255,0
"Selected color: RGB(0,255,0)"
Пример
Давайте создадим флаг, который принимает список строк:
package main
import (
"flag"
"fmt"
"strings"
)
type StringList []string
func (s *StringList) String() string {
return strings.Join(*s, ", ")
}
func (s *StringList) Set(value string) error {
*s = strings.Split(value, ",")
return nil
}
func main() {
var names StringList
flag.Var(&names, "names", "John,Jane", "comma-separated list of names")
flag.Parse()
fmt.Printf("Names: %s\n", names.String())
fmt.Printf("Count: %d\n", len(names))
}
Результат выполнения кода:
$ go run main.go -names Alice,Bob,Charlie
"Names: Alice, Bob, Charlie"
"Count: 3"
Пример
Давайте создадим флаг с валидацией значений:
package main
import (
"flag"
"fmt"
"strconv"
)
type Port struct {
Value int
}
func (p *Port) String() string {
return strconv.Itoa(p.Value)
}
func (p *Port) Set(value string) error {
port, err := strconv.Atoi(value)
if err != nil {
return err
}
if port < 1 || port > 65535 {
return fmt.Errorf("port must be between 1 and 65535")
}
p.Value = port
return nil
}
func main() {
var port Port
flag.Var(&port, "port", "8080", "server port number (1-65535)")
flag.Parse()
fmt.Printf("Server port: %d\n", port.Value)
}
Результат выполнения кода:
$ go run main.go -port 9090
"Server port: 9090"
$ go run main.go -port 70000
"invalid value \"70000\" for flag -port: port must be between 1 and 65535"
Смотрите также
-
функцию
flag.String,
которая определяет строковый флаг -
функцию
flag.Int,
которая определяет целочисленный флаг -
функцию
flag.Bool,
которая определяет булев флаг -
функцию
flag.Parse,
которая разбирает переданные аргументы командной строки