Go 语言基础之常用包【flag、time、strconv、io】

1、命令行参数包 flag 

flag 包就是一个用来解析命令行参数的工具。

1.1、os.Args

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

运行结果:

        osArgs 的本质是一个字符串切片,它的第一个索引 0 存储的是可执行文件的名称,之后的参数才是用户输入的参数。

1.2、flag 包的基本使用

flag 支持的的命令行参数主要有:数值类型、字符串和时间间隔(time.Duration)等。

  • 对于 duration 类型,合法的单位有"ns"、“us” 、“µs”、“ms”、“s”、“m”、“h”。用的时候需要带上单位,比如 1h30m。

1.2.1、命令行参数的定义

        命令行参数的定义有两种方式:一种是不带初始值的(flag.Type),一种是带初始值的(flag.TypeVar)。

flag.Type(flag名, 默认值, 帮助信息)
    name := flag.String("name", "张三", "姓名")age := flag.Int("age", 18, "年龄")married := flag.Bool("married", false, "婚否")delay := flag.Duration("delay", 0, "时间间隔")

通过查看源码我们可以发现,使用这种方式返回的是一个指针,而不是值:

所以在读取的时候需要使用 * 来取出指针的值。 

flag.TypeVar(Type指针, flag名, 默认值, 帮助信息)
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, "时间间隔")

1.2.2、解析命令行参数 flag.Parse()

定义好命令行参数之后,需要显式调用解析命令行参数方法(flag.Parse())才能生效,不然读取不到参数。

flag 支持的命令行参数格式有以下几种:

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

对于布尔类型的参数一般用等号来传递,不然解析不到布尔值之后的参数,并且会把布尔值及其之后的参数当做其它参数。

使用 go run ./flag.go 执行或者 go build 编译 go 文件再执行:

​​go build ./flag.go

1.2.3、其它参数 

        除了我们定义的参数之外,还可以有其它参数,但是必须跟在我们定义的最后一个参数后面,此外 flag 提供了一些方法来获取其它参数的属性:

	//返回命令行参数后的其他参数fmt.Println(flag.Args())//返回命令行参数后的其他参数个数fmt.Println(flag.NArg())//返回使用的命令行参数个数fmt.Println(flag.NFlag())

1.3、测试

package mainimport ("flag""fmt""time"
)func main() {var age intvar married boolvar delay time.Durationname := flag.String("name", "张三", "姓名")flag.IntVar(&age, "age", 18, "年龄")flag.BoolVar(&married, "married", false, "婚否")flag.DurationVar(&delay, "delay", 0, "延迟的时间间隔")//解析命令行参数flag.Parse()fmt.Println(*name, age, married, delay)//返回命令行参数后的其他参数fmt.Println(flag.Args())//返回命令行参数后的其他参数个数fmt.Println(flag.NArg())//返回使用的命令行参数个数fmt.Println(flag.NFlag())
}

测试1(自定义参数 + 其它参数): 

测试2(全为其它参数):

2、时间包 time

Go 语言中使用time.Time类型表示时间。我们可以通过time.Now函数获取当前的时间对象,然后从时间对象中可以获取到年、月、日、时、分、秒等信息。

func main() {now := time.Now()// 2024-05-06 19:44:56.6410767 +0800 CST m=+0.004404001fmt.Println(now)// 现在是2024年5月6日19时46分38秒fmt.Printf("现在是%d年%d月%d日%d时%d分%d秒", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
}

2.1、Location和time zone

这个还是比较实用的,因为 time.LoadLocation 依赖系统的时区数据库,在不太确定程序运行环境的情况下建议先自定义时区偏移量(比如北京时间就是东八区时间,需要在UTC基础上+8个小时)然后使用time.FixedZone的方式指定时区。

    // 时差(单位:s)diffSeconds := int((8 * time.Hour).Seconds()) // float 转 int// 北京时间beijing := time.FixedZone("Beijing Time", diffSeconds) // 返回 *Location

2.2、Unix Time

        Unix Time是自1970年1月1日 00:00:00 UTC 至当前时间经过的总秒数,我们可以通过 time 提供的方法获得当前的 Unix 秒/毫秒数(微秒、纳秒用不上):

func main() {now := time.Now()// 都是返回 int64 类型的整数timestamp := now.Unix()millisecond := now.UnixMilli() // 1714996867s,1714996867336msfmt.Printf("%ds,%dms", timestamp, millisecond) 
}

我们也可以把秒/毫秒数(int64)转为时间:

func main() {now := time.Now()// 都是返回 int64 类型的整数second := now.Unix()// 第2个参数为不足1秒的纳秒数timeValue := time.Unix(int64(second), 22)fmt.Println(timeValue) // 2024-05-06 20:01:07.000000022 +0800 CST
}

2.3、时间间隔 

time 包中定义的时间间隔类型的常量如下:

const (Nanosecond  Duration = 1Microsecond          = 1000 * NanosecondMillisecond          = 1000 * MicrosecondSecond               = 1000 * MillisecondMinute               = 60 * SecondHour                 = 60 * Minute
)

用的时候直接用常量 * 单位即可,下面是 time.Duration 常用的一些方法:


func main() {now := time.Now()// 这里 Add 方法的参数为 time.Duration 类型later := now.Add(3 * time.Hour)// 三个小时以后是: 2024-05-06 23:07:28.3043137 +0800 CST m=+10800.004676401fmt.Println("三个小时以后是: ", later)// Sub 方法的返回值为 time.Duration 类型fmt.Println(now.Sub(later)) // -3h0m0s// now 是否在 later 之前fmt.Println(now.Before(later)) // true// now 是否在 later 之后fmt.Println(now.After(later)) // false// 加载东京所在的时区tokyo, _ := time.LoadLocation("Asia/Tokyo")// 加载上海所在的时区shanghai, _ := time.LoadLocation("Asia/Shanghai")tk := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), tokyo)sh := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), shanghai)// 判断两个时间是否相同,会考虑时区的影响fmt.Println(now.Equal(tk)) // falsefmt.Println(now.Equal(sh)) // true
}

2.4、时间格式化

注意:Go 语言诞生于2006 年 1 月 2 日下午15 点 4 分 5 秒,它的时间格式化模板用的也正是这个时间!

func main() {now := time.Now()// 格式化模板:2006-01-02 15:04:05.000fmt.Println(now.Format("2006-01-02 15:04:05")) // 2024-05-06 20:24:57
}

2.5、解析时间字符串 

func main() {now := time.Now()// 格式化模板:2006-01-02 15:04:05.000// 两个参数的长度必须对应上t1, _ := time.Parse("2006-01-02 15:04:05", now.String()[0:19])fmt.Println(t1) // 2024-05-06 20:34:59 +0000 UTC
}

在解析时,可额外指定时区信息:

func main() {now := time.Now()sh, _ := time.LoadLocation("Asia/Shanghai")// 格式化模板:2006-01-02 15:04:05.000// 按照指定时区和指定格式解析字符串时间t1, _ := time.ParseInLocation("2006-01-02 15:04:05", now.String()[0:19], sh)fmt.Println(t1) // 2024-05-06 20:40:24 +0800 CST
}

3、strconv

Go 语言中 strconv 包实现了基本数据类型和其字符串表示的相互转换,主要有以下常用函数: Atoi()、Itoa()、parse系列、format系列、append系列。

3.1、string 转 int(Atoi)

        为什么是 Atoi 而不是 Atos 呢?这是因为C语言中没有string类型而是用字符数组(array)表示字符串。

func main() {str := "100"num, _ := strconv.Atoi(str)fmt.Printf("%T,%v", num, num) // int,100
}

3.2、int 转 string(Itoa)

func main() {num := 100str := strconv.Itoa(num)fmt.Printf("%T,%v", str, str) // string,100
}

3.3、Parse 系列

        Parse类函数用于转换字符串给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()。

	b, _ := strconv.ParseBool("true")f, _ := strconv.ParseFloat("3.1415", 64)i, _ := strconv.ParseInt("-2", 10, 64)u, _ := strconv.ParseUint("2", 10, 64)

3.4、Format 系列

Format系列函数实现了将给定类型数据格式化为string类型数据的功能。

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

这里需要特别说明的是:

func FormatFloat(f float64, fmt byte, prec, bitSize int) string
  • 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。

3.5、其它方法

func CanBackquote(s string) bool

表示返回字符串s是否可以不被修改的表示为一个单行的、没有空格和tab之外控制字符的反引号字符串。

4、文件操作

        计算机中的文件是存储在外部介质(通常是磁盘)上的数据集合,文件分为文本文件和二进制文件(音频、视频)等。

4.1、文件的打开与关闭

    // 返回文件对象指针和error对象file, _ := os.Open("./main.go")defer file.Close()

4.2、普通方式读取文件

读取文件的方法源码:

func (f *File) Read(b []byte) (n int, err error)

其中,b 是一个用于存放文件读取进来的字节,相当于是一个缓冲区,可以重复使用。

func main() {file, _ := os.Open("./main.go")defer file.Close()// 开辟一个大小为128的字节切片用来存储文件tmp := make([]byte, 128)n, err := file.Read(tmp)if err == io.EOF {fmt.Println("读取完毕")return}if err != nil {fmt.Println("读取失败")return}fmt.Printf("读取了%d字节的数据\n", n)fmt.Println(string(tmp[:n]))
}

        这种方式读取的缺点是我们并不能知道文件的大小,如果定义的缓冲区太大就浪费资源了,但是定义小了又读取不完整(因为只能读一次,不能循环利用),所以我们更多的是使用下面这种循环读取的方式:

func main() {file, _ := os.Open("./main.go")defer file.Close()var content []byte// 开辟一个大小为128的字节切片用来存储文件tmp := make([]byte, 128)for {n, err := file.Read(tmp)if err == io.EOF {fmt.Println("读取完毕")break}if err != nil {fmt.Println("读取失败")return}content = append(content, tmp[:n]...)}fmt.Println(string(content))
}

 这种方法每次都会从文件读取 128 字节数据,Read 方法的返回值是一个切片,所以需要使用 append 函数来汇总到 content 切片当中;从下一次读取,又会把上一次的结果覆盖掉,

4.3、使用 bufio 读取文件

bufio 是在 file 的基础上封装了一层API,支持更多的功能:

func main() {file, _ := os.Open("./main.go")defer file.Close()scanner := bufio.NewScanner(file)for scanner.Scan() {fmt.Println(scanner.Text())}if err := scanner.Err(); err != nil {fmt.Println("读取失败", err)}
}

4.4、使用 os.ReadFile 读取整个文件

os包(go1.16之前是 io.ioutil )的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入:

func main() {content, err := os.ReadFile("./main.go")if err != nil {fmt.Println("读取失败")return}fmt.Println(string(content))
}

4.5、文件写入操作

os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能:

func OpenFile(name string, flag int, perm FileMode) (*File, error) {...
}

其中 name:要打开的文件名 flag:打开文件的模式。 模式有以下几种:

模式含义
os.O_WRONLY 只写
os.O_CREATE创建文件
os.O_RDONLY 只读
os.O_RDWR读写
os.O_TRUNC清空
os.O_APPEND追加

4.5.1、Write 和 WriteString 

func main() {// 0666是文件的权限设置,表示文件所有者、所属组和其他用户都有读写权限file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)if err != nil {fmt.Println("操作文件失败", err)return}defer file.Close()str := "Hello let's Go\n"file.Write([]byte(str))file.WriteString("Hello Big Data")
}

运行结果:

4.5.2、bufio.NewWriter

效果都是一样的,只不过是不同包下的方法:

func main() {// 0666是文件的权限设置,表示文件所有者、所属组和其他用户都有读写权限file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)if err != nil {fmt.Println("操作文件失败", err)return}defer file.Close()writer := bufio.NewWriter(file)for i := 0; i < 10; i++ {writer.WriteString("Hello let's Go\n") //将数据先写入缓存}writer.Flush() // 将缓存中的内容写入文件
}

4.5.3、os.WriteFile

        os 包(go1.16之前是 io.ioutil )下的 WriteFile 可以一次将一个byte切片内的数据全部写入文件当中。只不过不能指定写入模式,比如追加等。

func main() {str:="Hello let's Go"err := os.WriteFile("./test.txt", []byte(str), 0666)if err != nil {fmt.Println("写入失败")return}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并行执行线程资源管理方式——《OceanBase 并行执行》系列 3

在某些特定场景下&#xff0c;由于需要等待线程资源&#xff0c;并行查询会遇到排队等待的情况。本篇博客将介绍如何管理并行执行线程资源&#xff0c;以解决这种问题。 《OceanBase并行执行》系列的内容分为七篇博客&#xff0c;本篇是其中的第三篇。前2篇如下&#xff1a; 一…

基于BP神经网络的16QAM解调算法matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ........................................................... % 第一部分&#xff1a;加载并…

06.命令的组合使用

命令的组合使用 1.查询当前整个系统每个进程的线程数 我们经常遇到这样的问题&#xff0c;比如某台服务器的CPU 使用率飙升&#xff0c;通过top命令查看是某个程序&#xff08;例如java&#xff09;占用的cpu比较大&#xff0c;现在需要查询java各个进程下的线程数情况。可以通…

jsp 实验12 servlet

一、实验目的 掌握怎样在JSP中使用javabean 二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握servlet的用法。【参考课本 上机实验1 】 三、源代码以及执行结果截图&#xff1a; 源代碼&#xff1a; inputVertex.jsp&#xff1a; <% page lang…

MacOS下载安装JDK8

一、前言 今天给苹果电脑安装JDK环境&#xff0c;后续打算把Mac系统也用起来&#xff0c;也体验一把用苹果系统开发。 JDK就不过多介绍了&#xff0c;大家都是JAVA开发&#xff0c;JDK就是JAVA开发的必要环境。目前已经更新到JDK20了&#xff0c;不过我是不会更新的&#xff0…

Linux|了解如何使用 awk 内置变量

引言 当我们揭开 Awk 功能部分时&#xff0c;我们将介绍 Awk 中内置变量的概念。您可以在 Awk 中使用两种类型的变量&#xff1a;用户定义的变量和内置变量。 内置变量的值已经在 Awk 中定义&#xff0c;但我们也可以仔细更改这些值&#xff0c;内置变量包括&#xff1a; FILEN…

LeNet-5上手敲代码

LeNet-5 LeNet-5由Yann LeCun在1998年提出&#xff0c;旨在解决手写数字识别问题&#xff0c;被认为是卷积神经网络的开创性工作之一。该网络是第一个被广泛应用于数字图像识别的神经网络之一&#xff0c;也是深度学习领域的里程碑之一。 LeNet-5的整体架构&#xff1a; 总体…

免费思维13招之四:主副型思维

免费思维13招之四:主副型思维 本节,给你分享一下产品型思维的第二种子思维:主副型思维 什么是主副型思维呢?传统的主副型思维是指对企业的核心、利润最高的产品进行收费,一些附加品、延伸产品进行让利,赠送给客户。 但是这早已过时了,现在升级之后的产品型思维,就是将…

VisualGDB:Linux静态库项目创建、编译及库的使用

接上篇《VisualGDB&#xff1a;Linux动态库项目创建、编译及库的使用》&#xff0c;静态库的创建和使用与动态库基本无差别&#xff0c;唯一需要做的就是指定项目生成静态库。 一、指定项目生成静态库 二、重新构建和编译项目 这里注意&#xff0c;同样要copy一个libxxx.so格式…

Linux 无名信号量(Semaphore)的使用

目录 一、无名信号量的概念二、无名信号量相关函数三、信号量的使用步骤四、应用场景五、测试代码 一、无名信号量的概念 Linux无名信号量&#xff08;Semaphore&#xff09;   在Linux操作系统中&#xff0c;信号量&#xff08;Semaphore&#xff09;是一种用于进程间或线程…

内网穿透速度慢

内网穿透速度慢原因及优化策略 在计算机网络应用中&#xff0c;内网穿透是一个常见的需求&#xff0c;它允许外部网络访问位于内部网络&#xff08;如企业局域网或家庭网络&#xff09;中的设备或服务。然而&#xff0c;有时用户在进行内网穿透时会遇到速度慢的问题&#xff0…

AI视频教程下载:给企业管理层和商业精英的ChatGpt课程

课程内容大纲&#xff1a; 1-引言 2-面向初学者的生成性人工智能 3-与ChatGPT一起学习提示101 详细介绍了如何使用ChatGPT的六种沟通模式&#xff0c;并提供了各种实际应用场景和示例&#xff1a; **Q&A模式&#xff08;问题与答案模式&#xff09;**&#xff1a; - 这…

打印机处于脱机状态如何恢复到正常状态?最简单!

当打印机一直处于脱机状态但打印机重启了好几遍仍然无效果时&#xff0c;尝试以下方法或许会成功&#xff01; 1.打开设置&#xff0c;在主页界面会有它的推荐设置&#xff0c;如上图&#xff0c;此时只需要点击“打印机和扫描仪”这个方框即可 2.但也并不是每次都会有推荐设置…

从零开始!学习绘制3D表情的详细指南

在2020 年的苹果全球开发者大会(WWDC)&#xff0c;苹果发布了新的 macOS 11(又名 Big Sur)。其中在UI视觉方面macOS Big Sur 系统最大的变化就是图标上&#xff0c; Big Sur更新了很多新设计风格的 3D应用图标&#xff0c;3D设计的确可以提升UI整体的视觉氛围&#xff0c;并且现…

wsl2安装rancher并导入和创建k8s集群

环境准备 安装wsl2点击此文]ubuntu20.04安装docker 点击此文,安装完成后docker镜像仓库改成阿里云镜像加速地址.如果不熟请点击此文 docker 安装rancher 启动wsl,根据官方文档以root身份执行 sudo docker run -d --restartunless-stopped -p 80:80 -p 443:443 --privileged …

《基于GNU-Radio和USRP的雷达通信系统的实现》文献阅读

文章目录 前言一、摘要二、引言三、联合系统实施1、基本原理2、实验方案 四、软件设置1、发射机2、接收机 五、实验结果1、实验设置2、波形3、室内外对比4、不同参数的结果 六、结论七、参考文献八、论文自取九、阅读收获 前言 本文记录《基于GNU-Radio和USRP的雷达通信系统的实…

2024粤港澳青少年信息学创新大赛C++知识点汇总和真题训练

2024粤港澳青少年信息学创新大赛C知识点汇总和真题训练 知识汇总 真题训练 程序设计语言C是一种解释性语言。 A.正确 B.错误 Python是一种编译型语言。 A.正确 B.错误 误 RAM&#xff08;随机存取存储器&#xff09;是一种易失性存储设备。 A.正确 B.错误 Java…

Docker-harbor

一、搭建本地私有仓库 1.1 下载Registry镜像 1.2 添加本地私有仓库配置 1.3 重启服务并运行Registry容器 1.4.容器的操作 1.4.1 拉取Nginx镜像并为镜像打标签 1.4.2 上传到私有仓库 1.4.3 列出私有仓库所有镜像 1.4.4 列出私有仓库的镜像的所有标签 1.4.5 先删除原有…

基于鸢尾花数据集实施自组织神经网络聚类分析

基于鸢尾花数据集实施自组织神经网络聚类分析 1. 自组织神经网络的基础知识2. 鸢尾花数据集的自组织分类3. SOM的无监督聚类 1. 自组织神经网络的基础知识 自组织神经网络也称自组织映射&#xff08;SOM&#xff09;或自组织特征映射&#xff08;SOFM&#xff09;&#xff0c;…

Coze扣子开发指南:用免费API自己创建插件

虽然Coze扣子现在插件商店已经有几百个插件了&#xff0c;但相对于海量人群的众多差异化需求&#xff0c;还是远远不够的。如果插件商店没有合适的插件&#xff0c;其实完成可以自己创建&#xff0c;过程也很简单&#xff0c;不需要编写任何代码。 首先打开个人空间&#xff0…