Введение
Цель этого лабораторного занятия - реализовать командную программу, которая поддерживает базовый разбор командной строки с использованием пакета 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 для разбора командных строковых флагов. Мы реализовали программу, которая поддерживает базовый разбор флагов и выводит разобранные параметры и любые оставшиеся позиционные аргументы.