Разбор командных строковых флагов в Go

Beginner

This tutorial is from open-source community. Access the source code

Введение

Цель этого лабораторного занятия - реализовать командную программу, которая поддерживает базовый разбор командной строки с использованием пакета flag в Golang.

Командные строковые флаги

Реализуйте программу на Golang, которая разбирает командные строковые флаги и выводит разобранные параметры и любые оставшиеся позиционные аргументы. Программа должна поддерживать следующие флаги:

  • word: строковый флаг со значением по умолчанию "foo".

  • numb: целочисленный флаг со значением по умолчанию 42.

  • fork: булевский флаг со значением по умолчанию false.

  • svar: строковый флаг, который использует существующую переменную, объявленную в другом месте программы.

  • Программа должна использовать пакет flag для разбора командных строковых флагов.

  • Программа должна выводить разобранные параметры и любые оставшиеся позиционные аргументы.

  • Программа должна поддерживать флаги word, numb, fork и svar, описанные выше.

## Чтобы экспериментировать с программой командных строковых флагов,
## лучше сначала скомпилировать ее, а затем запустить полученный
## бинарник напрямую.
$ go build command-line-flags.go

## Попробуйте запустить скомпилированную программу, сначала
## передав значения для всех флагов.
$./command-line-flags -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
fork: true
svar: flag
tail: []

## Обратите внимание, что если вы опустите флаги, они
## автоматически берут свои значения по умолчанию.
$./command-line-flags -word=opt
word: opt
numb: 42
fork: false
svar: bar
tail: []

## Оставшиеся позиционные аргументы можно указать после
## любых флагов.
$./command-line-flags -word=opt a1 a2 a3
word: opt
...
tail: [a1 a2 a3]

## Обратите внимание, что пакет `flag` требует, чтобы все
## флаги были указаны перед позиционными аргументами
## (иначе флаги будут интерпретироваться как позиционные
## аргументы).
$./command-line-flags -word=opt a1 a2 a3 -numb=7
word: opt
numb: 42
fork: false
svar: bar
tail: [a1 a2 a3 -numb=7]

## Используйте флаги `-h` или `--help`, чтобы получить
## автоматически сгенерированный текст помощи для
## командной программы.
$./command-line-flags -h
Usage of./command-line-flags:
-fork=false: a bool
-numb=42: an int
-svar="bar": a string var
-word="foo": a string

## Если вы укажете флаг, который не был определен для
## пакета `flag`, программа выведет сообщение об ошибке
## и снова покажет текст помощи.
$./command-line-flags -wat
flag provided but not defined: -wat
Usage of./command-line-flags:
...

Ниже представлен полный код:

// [_Command-line flags_](https://en.wikipedia.org/wiki/Command-line_interface#Command-line_option)
// - это распространенный способ указания параметров для
// командных программ. Например, в `wc -l` флаг `-l`
// является командным строковым флагом.

package main

// Go предоставляет пакет `flag`, поддерживающий базовый
// разбор командных строковых флагов. Мы будем использовать
// этот пакет для реализации нашей примерной командной
// программы.
import (
    "flag"
    "fmt"
)

func main() {

    // Доступны базовые объявления флагов для строковых,
    // целочисленных и булевых параметров. Здесь мы
    // объявляем строковый флаг `word` со значением по
    // умолчанию `"foo"` и кратким описанием. Эта функция
    // `flag.String` возвращает указатель на строку (а не
    // значение строки); мы увидим, как использовать этот
    // указатель ниже.
    wordPtr := flag.String("word", "foo", "a string")

    // Это объявляет флаги `numb` и `fork`, используя
    // аналогичный подход, как для флага `word`.
    numbPtr := flag.Int("numb", 42, "an int")
    forkPtr := flag.Bool("fork", false, "a bool")

    // Также можно объявить параметр, который использует
    // существующую переменную, объявленную в другом месте
    // программы. Обратите внимание, что мы должны передать
    // указатель на функцию объявления флага.
    var svar string
    flag.StringVar(&svar, "svar", "bar", "a string var")

    // Когда все флаги объявлены, вызовите `flag.Parse()`,
    // чтобы выполнить разбор командной строки.
    flag.Parse()

    // Здесь мы просто выведем разобранные параметры и
    // любые оставшиеся позиционные аргументы. Обратите
    // внимание, что мы должны разыменовать указатели,
    // например, с помощью `*wordPtr`, чтобы получить
    // фактические значения параметров.
    fmt.Println("word:", *wordPtr)
    fmt.Println("numb:", *numbPtr)
    fmt.Println("fork:", *forkPtr)
    fmt.Println("svar:", svar)
    fmt.Println("tail:", flag.Args())
}

Резюме

В этом лабораторном занятии мы узнали, как использовать пакет flag в Golang для разбора командных строковых флагов. Мы реализовали программу, которая поддерживает базовый разбор флагов и выводит разобранные параметры и любые оставшиеся позиционные аргументы.