func (a *Argument) String(defVal ...string) string {
	def := ""
	if len(defVal) == 1 {
		def = defVal[0]
	}
	if a.Value == nil || a.Arrayed {
		return def
	}
	if str, ok := a.Value.(string); ok {
		return str
	}
	return def
}
String argument value to string
package gcli
import (
	"fmt"
	"strconv"
	"strings"
	"github.com/gookit/goutil/strutil"
)
var emptyArg = &Argument{}
type Arguments struct {
	name string
	args []*Argument
	argsIndexes map[string]int
	validateNum bool
	hasArrayArg bool
	hasOptionalArg bool
}
func (ags *Arguments) SetName(name string) {
	ags.name = name
}
func (ags *Arguments) SetValidateNum(validateNum bool) {
	ags.validateNum = validateNum
}
func (ags *Arguments) ParseArgs(args []string) (err error) {
	var num int
	inNum := len(args)
	for i, arg := range ags.args {
		num = i + 1
		if num > inNum {  
			if arg.Required {
				return fmt.Errorf("must set value for the argument: %s(position#%d)", arg.ShowName, arg.index)
			}
			break
		}
		if arg.Arrayed {
			err = arg.bindValue(args[i:])
			inNum = num  
		} else {
			err = arg.bindValue(args[i])
		}
		if err != nil {
			return
		}
	}
	if ags.validateNum && inNum > num {
		return fmt.Errorf("entered too many arguments: %v", args[num:])
	}
	return
}
func (ags *Arguments) AddArg(name, desc string, requiredAndArrayed ...bool) *Argument {
	newArg := NewArgument(name, desc, requiredAndArrayed...)
	return ags.AddArgument(newArg)
}
func (ags *Arguments) AddArgByRule(name, rule string) *Argument {
	mp := parseSimpleRule(name, rule)
	required := strutil.MustBool(mp["required"])
	newArg := NewArgument(name, mp["desc"], required)
	if defVal := mp["default"]; defVal != "" {
		newArg.Value = defVal
	}
	return ags.AddArgument(newArg)
}
func (ags *Arguments) BindArg(arg *Argument) *Argument {
	return ags.AddArgument(arg)
}
func (ags *Arguments) AddArgument(arg *Argument) *Argument {
	if ags.argsIndexes == nil {
		ags.argsIndexes = make(map[string]int)
	}
	name := arg.goodArgument()
	if _, has := ags.argsIndexes[name]; has {
		panicf("the argument name '%s' already exists in command '%s'", name, ags.name)
	}
	if ags.hasArrayArg {
		panicf("have defined an array argument, you cannot add argument '%s'", name)
	}
	if arg.Required && ags.hasOptionalArg {
		panicf("required argument '%s' cannot be defined after optional argument", name)
	}
	arg.index = len(ags.args)
	ags.argsIndexes[name] = arg.index
	ags.args = append(ags.args, arg)
	if !arg.Required {
		ags.hasOptionalArg = true
	}
	if arg.Arrayed {
		ags.hasArrayArg = true
	}
	return arg
}
func (ags *Arguments) Args() []*Argument {
	return ags.args
}
func (ags *Arguments) HasArg(name string) bool {
	_, ok := ags.argsIndexes[name]
	return ok
}
func (ags *Arguments) HasArgs() bool {
	return len(ags.argsIndexes) > 0
}
func (ags *Arguments) HasArguments() bool {
	return len(ags.argsIndexes) > 0
}
func (ags *Arguments) Arg(name string) *Argument {
	i, ok := ags.argsIndexes[name]
	if !ok {
		return emptyArg
	}
	return ags.args[i]
}
func (ags *Arguments) ArgByIndex(i int) *Argument {
	if i < len(ags.args) {
		return ags.args[i]
	}
	return emptyArg
}
type Argument struct {
	Name string
	Desc string
	ShowName string
	Required bool
	Arrayed bool
	Value interface{}
	Handler func(val interface{}) interface{}
	Validator func(val interface{}) (interface{}, error)
	index int
}
func NewArgument(name, desc string, requiredAndArrayed ...bool) *Argument {
	var arrayed, required bool
	if ln := len(requiredAndArrayed); ln > 0 {
		required = requiredAndArrayed[0]
		if ln > 1 {
			arrayed = requiredAndArrayed[1]
		}
	}
	return &Argument{
		Name: name,
		Desc: desc,
		Required: required,
		Arrayed:  arrayed,
	}
}
func (a *Argument) SetArrayed() *Argument {
	a.Arrayed = true
	return a
}
func (a *Argument) Init() *Argument {
	a.goodArgument()
	return a
}
func (a *Argument) goodArgument() string {
	name := strings.TrimSpace(a.Name)
	if name == "" {
		panicf("the command argument name cannot be empty")
	}
	if !goodName.MatchString(name) {
		panicf("the command argument name '%s' is invalid, must match: %s", name, regGoodName)
	}
	a.Name = name
	if a.ShowName == "" {
		a.ShowName = name
	}
	return name
}
func (a *Argument) HelpName() string {
	if a.Arrayed {
		return a.ShowName + "..."
	}
	return a.ShowName
}
func (a *Argument) With(fn func(arg *Argument)) *Argument {
	if fn != nil {
		fn(a)
	}
	return a
}
func (a *Argument) WithValidator(fn func(interface{}) (interface{}, error)) *Argument {
	a.Validator = fn
	return a
}
func (a *Argument) SetValue(val interface{}) error {
	return a.bindValue(val)
}
func (a *Argument) GetValue() interface{} {
	val := a.Value
	if a.Handler != nil {
		return a.Handler(val)
	}
	return val
}
func (a *Argument) Int(defVal ...int) int {
	def := 0
	if len(defVal) == 1 {
		def = defVal[0]
	}
	if a.Value == nil || a.Arrayed {
		return def
	}
	if intVal, ok := a.Value.(int); ok {
		return intVal
	}
	if str, ok := a.Value.(string); ok {
		val, err := strconv.Atoi(str)
		if err == nil {
			return val
		}
	}
	return def
}