1. 程式人生 > >go語言解析命令列引數的實現

go語言解析命令列引數的實現

一、實現程式碼如下

// fffggg project main.go package main

import (     "flag"     "fmt" )

func main() {

    var num int     var mode string     var encrypt bool

    // 具體用法如下:

    // command -flagname     // command --flagname     // command -flagname=     // command --flagname=     // 注意“=”號前面和後面不能有空格

    // 第一步,定義Flag引數     flag.IntVar(&num, "num", 38, "--num the password length")     flag.StringVar(&mode, "mode", "mix", "--mode the password generate mode")     flag.BoolVar(&encrypt, "encrypt", true, "--encrypt the password use RSA")

    // 第二步,呼叫flag.Parse()解析命令列引數到定義的Flag     flag.Parse()

    // 呼叫Parse解析後,就可以直接使用繫結的變量了     fmt.Printf("num:%d mode:%s encrypt:%v\n", num, mode, encrypt) }

二、編譯後測試結果

./fffggg --num 3 --mode nnn --encrypt true num:3 mode:nnn encrypt:true

./fffggg --num 3 --mode nnn --encrypt false num:3 mode:nnn encrypt:true

三、出現錯誤解決方法

將go/src/flag/flag.go中下面程式碼的紅色部分程式碼提前即可

// parseOne parses one flag. It reports whether a flag was seen. func (f *FlagSet) parseOne() (bool, error) {     if len(f.args) == 0 {         return false, nil     }     s := f.args[0]     if len(s) == 0 || s[0] != '-' || len(s) == 1 {         return false, nil     }     numMinuses := 1     if s[1] == '-' {         numMinuses++         if len(s) == 2 { // "--" terminates the flags             f.args = f.args[1:]             return false, nil         }     }     name := s[numMinuses:]     if len(name) == 0 || name[0] == '-' || name[0] == '=' {         return false, f.failf("bad flag syntax: %s", s)     }

    // it's a flag. does it have an argument?     f.args = f.args[1:]     hasValue := false     value := ""     for i := 1; i < len(name); i++ { // equals cannot be first         if name[i] == '=' {             value = name[i+1:]             hasValue = true             name = name[0:i]             break         }     }     m := f.formal     flag, alreadythere := m[name] // BUG     if !alreadythere {         if name == "help" || name == "h" { // special case for nice help message.             f.usage()             return false, ErrHelp         }         return false, f.failf("flag provided but not defined: -%s", name)     }

    // It must have a value, which might be the next argument.     if !hasValue && len(f.args) > 0 {         // value is the next arg         hasValue = true         value, f.args = f.args[0], f.args[1:]     }

    if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg         if hasValue {             if err := fv.Set(value); err != nil {                 return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)             }         } else {             if err := fv.Set("true"); err != nil {                 return false, f.failf("invalid boolean flag %s: %v", name, err)             }         }     } else {        // It must have a value, which might be the next argument.         if !hasValue && len(f.args) > 0 {             // value is the next arg             hasValue = true             value, f.args = f.args[0], f.args[1:]         }         if !hasValue {             return false, f.failf("flag needs an argument: -%s", name)         }         if err := flag.Value.Set(value); err != nil {             return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)         }     }     if f.actual == nil {         f.actual = make(map[string]*Flag)     }     f.actual[name] = flag     return true, nil }