Golang에서 사용자 지정 명령줄 플래그를 정의하는 방법



소개



명령줄 인터페이스에 익숙하다면 -h , -v , --name foo 등과 같은 플래그를 본 적이 있을 것입니다. 일부 플래그는 string , int , bool 등과 같은 기본 데이터 유형을 사용합니다. 나머지 플래그는 사용자 지정 플래그입니다. IP , URL , Array , Map 등과 같은 특정 패턴이나 데이터 구조를 사용하는 것입니다. Golang은 명령줄 플래그를 정의하기 위해 flag이라는 내장 라이브러리를 제공합니다. 플래그를 정의하기 위해 제공된 함수 중 일부는 flag.String , flag.Int 등과 같이 간단합니다. 하지만 사용자 정의 플래그는 어떻습니까? 이 기사에서는 Golang에서 사용자 지정 명령줄 플래그를 정의하는 몇 가지 방법을 배웁니다.

예시



문자열 값 목록을 허용하는 사용자 지정 플래그를 만들고 싶다고 가정해 보겠습니다. 플래그의 사용법은 다음과 같아야 합니다.

$ go run main.go --list a --list b,c,d
[a b c d]


다음은 사용자 지정 플래그를 정의하는 몇 가지 방법입니다.

플래그 바르


flag.Var은 사용자 지정 플래그를 정의하는 방법입니다. flag.Value 인터페이스를 구현하는 사용자 지정 구조체를 허용합니다.

type ListFlag []string

func (f *ListFlag) String() string {
    b, _ := json.Marshal(*f)
    return string(b)
}

func (f *ListFlag) Set(value string) error {
    for _, str := range strings.Split(value, ",") {
        *f = append(*f, str)
    }
    return nil
}

func main() {
    // foo and bar as a default value
    list := ListFlag([]string{"foo", "bar"})
    flag.Var(&list, "list", "your flag usage")

    flag.Parse()
    fmt.Println(list) // [foo bar a b c d]
}


주목해야 할 중요한 사항은 Set 방법입니다. 플래그가 호출될 때마다 Set 메서드가 호출됩니다.

플래그 기능


flag.Func은 사용자 지정 플래그를 정의하는 간단한 방법입니다. 후드 아래에서 flag.Var을 사용하므로 사용자 지정 구조체를 만들 필요가 없습니다.

func main() {
    list := ListFlag([]string{"foo", "bar"})
    flag.Func("list", "your flag usage", func(s string) error {
        for _, str := range strings.Split(s, ",") {
            list = append(list, str)
        }
        return nil
    })

    flag.Parse()
    fmt.Println(list) // [foo bar a b c d]
}


보시다시피 flag.Func의 마지막 매개변수는 이전 예제에서 구현한 Set 메서드입니다.

플래그 TextVar


flag.TextVargo1.19에 도입된 새로운 방식입니다. flag.Var 과 같이 후드 아래에서 flag.Func 을 사용하지만 encoding.TextUnmarshaler 인터페이스 대신 encoding.TextMarshalerflag.Value 인터페이스를 허용합니다. 이는 사용자 지정 구조체를 구현할 필요 없이 big.Int , netip.Addrtime.Time 과 같은 내장 구조체를 플래그로 사용할 수 있음을 의미합니다.

type ListFlag []string

func (f *ListFlag) MarshalText() ([]byte, error) {
    return json.Marshal(*f)
}

func (f *ListFlag) UnmarshalText(b []byte) error {
    for _, str := range strings.Split(string(b), ",") {
        *f = append(*f, str)
    }
    return nil
}

func main() {
    list := ListFlag([]string{"foo", "bar"})
    flag.TextVar(&list, "list", &list, "your flag usage")

    flag.Parse()
    fmt.Println(list)
}


보시다시피 flag.Var과 유사하지만 MarshalTextUnmarshalText 메소드 대신 StringSet을 사용합니다.

결론



이제 Golang에서 사용자 지정 명령줄 플래그를 정의하는 몇 가지 방법을 알게 되었습니다. flag 패키지에 대해 자세히 알아보려면 공식 문서 here을 참조하세요.

읽어 주셔서 감사합니다!

좋은 웹페이지 즐겨찾기