Интерфейс flag.Value

Интерфейс flag.Value определяет методы, которые должны быть реализованы для создания пользовательских флагов командной строки. Он позволяет интегрировать произвольные типы данных в систему парсинга флагов пакета flag. Интерфейс содержит два метода: String, который возвращает строковое представление значения, и Set, который устанавливает значение из строки.

Синтаксис

gotype Value interface {
  String() string
  Set(string) error
}

Пример

Создадим пользовательский тип для флага, который принимает список строк через запятую:

gopackage main

import (
  "flag"
  "fmt"
  "strings"
)

type StringSlice []string

func (s *StringSlice) String() string {
  return strings.Join(*s, ",")
}

func (s *StringSlice) Set(value string) error {
  *s = strings.Split(value, ",")
  return nil
}

func main() {
  var names StringSlice
  flag.Var(&names, "names", "Comma-separated list of names")
  flag.Parse()

  fmt.Printf("Names: %v\n", names)
}

Результат выполнения кода с флагом -names=John,Jane,Bob:

go"Names: [John Jane Bob]"

Пример

Создадим пользовательский тип для флага, который принимает диапазон чисел в формате min-max:

gopackage main

import (
  "flag"
  "fmt"
  "strconv"
  "strings"
)

type Range struct {
  Min int
  Max int
}

func (r *Range) String() string {
  return fmt.Sprintf("%d-%d", r.Min, r.Max)
}

func (r *Range) Set(value string) error {
  parts := strings.Split(value, "-")
  if len(parts) != 2 {
    return fmt.Errorf("invalid range format, expected min-max")
  }
  
  min, err := strconv.Atoi(parts[0])
  if err != nil {
    return err
  }
  
  max, err := strconv.Atoi(parts[1])
  if err != nil {
    return err
  }
  
  if min > max {
    return fmt.Errorf("min must be less than or equal to max")
  }
  
  r.Min = min
  r.Max = max
  return nil
}

func main() {
  var r Range
  flag.Var(&r, "range", "Range in format min-max")
  flag.Parse()

  fmt.Printf("Range: %d to %d\n", r.Min, r.Max)
}

Результат выполнения кода с флагом -range=10-20:

go"Range: 10 to 20"

Пример

Создадим пользовательский тип для флага, который принимает список целых чисел:

gopackage main

import (
  "flag"
  "fmt"
  "strconv"
  "strings"
)

type IntSlice []int

func (s *IntSlice) String() string {
  strs := make([]string, len(*s))
  for i, v := range *s {
    strs[i] = strconv.Itoa(v)
  }
  return strings.Join(strs, ",")
}

func (s *IntSlice) Set(value string) error {
  parts := strings.Split(value, ",")
  *s = make([]int, 0, len(parts))
  for _, part := range parts {
    num, err := strconv.Atoi(strings.TrimSpace(part))
    if err != nil {
      return err
    }
    *s = append(*s, num)
  }
  return nil
}

func main() {
  var numbers IntSlice
  flag.Var(&numbers, "numbers", "Comma-separated list of integers")
  flag.Parse()

  sum := 0
  for _, n := range numbers {
    sum += n
  }
  fmt.Printf("Sum: %d\n", sum)
}

Результат выполнения кода с флагом -numbers=1,2,3,4,5:

go"Sum: 15"

Смотрите также

  • функцию flag.Var,
    которая связывает пользовательский тип с флагом
  • функцию flag.StringVar,
    которая связывает строковую переменную с флагом
  • функцию flag.IntVar,
    которая связывает целочисленную переменную с флагом
  • функцию flag.BoolVar,
    которая связывает булеву переменную с флагом