标准库之 flag、strconv

一、flag库

  • flag库的作用同python中的 sys.argv 差不多,是Go语言自带的解析运行Go脚本时,后面跟着的参数(俗称:命令行参数)的一个库
  • 定义好flag之后,就能像登录mysql时一样,mysql -u root -h 192.168.30.20,这里的 -u 和 -h就是相当于flag定义好的参数名
  • flag接收的命令行参数可以直接使用,因为它们的类型是定义flag参数时已经指定好的

1. flag的简单替代

  • 若你只是想简单的获取命令行参数,可以使用 os.Args方法获取,只能接收成string类型,后面需要根据需求自己转换类型
package main

import (
	"fmt"
	"os"
)

// os.Args demo
func main() {
	//os.Args是一个[]string
	if len(os.Args) > 0 {
		for index, arg := range os.Args {
			fmt.Printf("args[%d]=%v\n", index, arg)
		}
	}
}

/*
go build .\test3.go
PS C:\GolandProjects\hsw_test> .\test3.exe a b c d 3e
args[0]=C:\GolandProjects\hsw_test\test3.exe
args[1]=a
args[2]=b
args[3]=c
args[4]=d
args[5]=3e
PS C:\GolandProjects\hsw_test> go run .\test3.go a b c d e
args[0]=C:\Users\hsw\AppData\Local\Temp\go-build686863642\b001\exe\test3.exe
args[1]=a
args[2]=b
args[3]=c
args[4]=d
args[5]=e

分析:上面用了两种执行方式:
1. 先build,再执行生成的编译文件test3.exe,在 test3.exe 后面跟上参数
2. 直接go run test3.go ,运行test3.go 文件(相当于在内存中编译后再执行编译内容,不会生成 .exe文件),test3.go 后面跟上参数
*/

2. flag的参数类型

  • flag包支持的命令行参数类型有boolintint64uintuint64float float64stringduration,在定义时,这些类型的首字母要大写
flag参数 有效值
字符串flag 合法字符串
整数flag 1234、0664、0x1234等类型,也可以是负数
浮点数flag 合法浮点数
bool类型flag 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
时间段flag 任何合法的时间段字符串。如”300ms”、”-1.5h”、”2h45m”
合法的单位有”ns”、”us” /“µs”、”ms”、”s”、”m”、”h”

3. flag参数的定义

  • 共有两种定义方式

(1)flag.Type()

定义语法: flag.Type(参数名, 默认值, 提示信息)

flag.Type(参数名, 默认值, 提示信息) 返回的是指针,解析之后需要用 * 来取值


示例:
package main

import (
	"flag"
	"fmt"
	"time"
)

func main() {
    //定义命令行参数方式1
	name := flag.String("name", "张三", "姓名")
	age := flag.Int("age", 18, "年龄")
	married := flag.Bool("married", false, "婚否")
	delay := flag.Duration("d", 0, "时间间隔")
	// 解析命令行参数,必须先定义再解析,只有解析之后程序才能接收到命令行参数
    // 需要注意的是,此时name、age、married、delay均为对应类型的指针**************
	flag.Parse()
	fmt.Println("111222333")
	fmt.Println(name, age, married, delay)
	fmt.Println(*name, *age, *married, *delay)
}

/*
PS C:\GolandProjects\hsw_test> go run .\test3.go -name=锅包肉 -age=18 -married=false -d=1s
111222333
0xc000020080 0xc00000a148 0xc00000a150 1s
锅包肉 18 false 1s
PS C:\GolandProjects\hsw_test>

分析:可以发现时间间隔类型,无需取值也可以直接输出值
*/

(2)flag.TypeVar()

定义语法: flag.TypeVar(指针变量, 参数名, 默认值, 提示信息)

示例:

package main

import (
	"flag"
	"fmt"
	"time"
)

func main6() {
	//定义命令行参数方式2
	var name string
	var age int
	var married bool
	var delay time.Duration
	flag.StringVar(&name, "name", "张三", "姓名")
	flag.IntVar(&age, "age", 18, "年龄")
	flag.BoolVar(&married, "married", false, "婚否")
	flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")

	//解析命令行参数
	flag.Parse()
	fmt.Println(name, age, married, delay)
	//返回命令行参数后的其他参数
	fmt.Println(flag.Args())
	//返回命令行参数后的其他参数个数
	fmt.Println(flag.NArg())
	//返回使用的命令行参数个数
	fmt.Println(flag.NFlag())
}

4. flag解析命令行参数

  • flag.Parse()方法用来解析上面定义的flag参数,只有解析之后程序才能接收到命令行参数
  • 只有命令行参数使用规定的写法,flag.Parse()才能正确解析
下面的flag为定义的参数名,xxx为参数值,命令行参数格式共有下面4种写法:
注意:布尔类型的参数必须使用等号的方式指定
注意:Flag解析在第一个非flag参数(单个“-”不是程序中定义的flag参数)之前停止,或者在终止符“–”之后停止

-flag xxx   // (使用空格,一个-符号)
--falg xxx  // (使用空格,两个-符号)
-flag=xxx   // (使用等号,一个-符号)
--falg=xxx  // (使用等号,两个-符号)

5. flag其他方法

flag.Args()  // 返回命令行参数后的其他参数,以[]string类型
flag.NArg()  // 返回命令行参数后的其他参数个数
flag.NFlag()  // 返回使用的命令行参数个数

二、strconv库

  • Go语言中strconv包实现了基本数据类型和字符串之间的相互转换
  • 这里只介绍了strconv库中常用的几个函数: Atoi()Itia()、parse系列、format系列、append系列
  • 浮点型和整型之间可以通过 int() float()函数直接强制转换,但是它们和字符串之间是不能直接用 string()转换的

1. string转换为int类型

  • Atoi()方法实现了字符串转换成整型
函数的定义:  func Atoi(s string) (i int, err error)

如果传入的字符串参数无法转换为int类型,就会返回错误

示例:
package main

import (
	"fmt"
	"strconv"
)

func main() {
	s1 := "100"
	i1, err := strconv.Atoi(s1)
	if err != nil {
		fmt.Println("can't convert to int")
	} else {
		fmt.Printf("type:%T value:%#v\n", i1, i1)  // type:int value:100
	}
}

2. int转换为string类型

  • Itoa()方法实现了整型转换成字符串类型
函数的定义:  func Itoa(i int) string

示例:
package main

import (
	"fmt"
	"strconv"
)

func main() {
	i2 := 200
	s2 := strconv.Itoa(i2)
	fmt.Printf("type:%T value:%#v\n", s2, s2)  // type:string value:"200"
}

3. Parse系列函数

  • Parse类函数作用是将字符串转换为指定类型的值
  • 共有如下几种方法 ParseBool()、ParseInt()、ParseUint()、ParseFloat()

(1)ParseBool()

函数的定义:  func ParseBool(str string) (value bool, err error)

- 返回字符串表示的bool值。它接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE;否则返回错误

(2)ParseInt()

函数的定义:  func ParseInt(s string, base int, bitSize int) (i int64, err error)

- 返回字符串表示的整数值,接受正负号

- base指定进制(2到36),如果base为0,则会从字符串前置判断,”0x”是16进制,”0”是8进制,否则是10进制

- bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64

- 返回的err是*NumErr类型的,如果语法有误,err.Error = ErrSyntax;如果结果超出类型范围err.Error = ErrRange

(3)ParseUnit()

函数的定义:  func ParseUint(s string, base int, bitSize int) (n uint64, err error)

- ParseUint类似ParseInt但不接受正负号,用于无符号整型

(4)ParseFloat()

函数的定义:  func ParseFloat(s string, bitSize int) (f float64, err error)

- 解析一个表示浮点数的字符串并返回其值

- 如果s合乎语法规则,函数会返回最为接近s表示值的一个浮点数(使用IEEE754规范舍入)

- bitSize指定了期望的接收类型,32是float32(返回值可以不改变精确值的赋值给float32),64是float64

- 返回值err是*NumErr类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值f为±Inf,err.Error= ErrRange

(5)示例

package main

import (
	"fmt"
	"strconv"
)

func main() {
	b, err1 := strconv.ParseBool("true")
	f, err2 := strconv.ParseFloat("3.1415", 64)
	i, err3 := strconv.ParseInt("-2", 10, 64)
	u, err4 := strconv.ParseUint("2", 10, 64)

	fmt.Println(b, err1)
	fmt.Println(f, err2)
	fmt.Println(i, err3)
	fmt.Println(u, err4)
}

/*
true <nil>
3.1415 <nil>
-2 <nil>    
2 <nil> 
*/

4. Format系列函数

  • Format系列函数实现了将给定类型数据格式化为string类型数据的功能
  • 共有如下几种方法 FormatBool()、FormatInt()、FormatUint()、FormatFloat()

(1)FormatBool()

函数的定义:  func FormatBool(b bool) string

- 根据b的值返回”true”或”false”

(2)FormatInt()

函数的定义:  func FormatInt(i int64, base int) string

- 返回i的base进制的字符串表示。base 必须在2到36之间,结果中会使用小写字母’a’到’z’表示大于10的数字

(3)FormatUint()

函数的定义:  func FormatUint(i uint64, base int) string

- 是FormatInt的无符号整数版本

(4)FormatFloat()

函数的定义:  func FormatFloat(f float64, fmt byte, prec, bitSize int) string

- 函数将浮点数表示为字符串并返回

- bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入

- fmt表示格式:’f’(-ddd.dddd)、’b’(-ddddp±ddd,指数为二进制)、’e’(-d.dddde±dd,十进制指数)、’E’(-d.ddddE±dd,十进制指数)、’g’(指数很大时用’e’格式,否则’f’格式)、’G’(指数很大时用’E’格式,否则’f’格式)

- prec控制精度(排除指数部分):对’f’、’e’、’E’,它表示小数点后的数字个数;对’g’、’G’,它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f

(5)示例

func main() {
	s1 := strconv.FormatBool(true)
	s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
	s3 := strconv.FormatInt(-2, 16)
	s4 := strconv.FormatUint(2, 16)

	fmt.Println(s1)
	fmt.Println(s2)
	fmt.Println(s3)
	fmt.Println(s4)

}

/*
true
3.1415E+00
-2        
2 
*/

5. 其他(了解即可)

(1)isPrint()

函数的定义:  func IsPrint(r rune) bool

- 返回一个字符是否是可打印的,和unicode.IsPrint一样,r必须是:字母(广义)、数字、标点、符号、ASCII空格

(2)CanBackquote()

函数的定义:  func CanBackquote(s string) bool

- 返回字符串s是否可以不被修改的表示为一个单行的、没有空格和tab之外控制字符的反引号字符串
posted @ 2024-03-06 10:38  BigSun丶  阅读(141)  评论(0)    收藏  举报