Go 语言新手笔记(四)

学到了 Go 语言本身的语法之后,开始步入 Go 的应用部分,掌握一个语言不得不接触的就是它对文件,网络的操作。

在正式进入主题之前不得不抱怨一下 Go 的官方编码规范中的代码缩进格式。曾经 Google 出的 Java 缩进规范是用两个空格(通常是用四个空格),并且是杜绝用  Tab 进行缩进的,因为 Tab 的宽度是不很确定的。

然而 Google 建议 Go 的代码格式化工具  gofmt 却反常规的强制使用 Tab 进行缩进,而且是。本人用 IntelliJ IDEA 编写 Go, 即使在 Go 的 Code Style 中把 Use tab character 去掉也是用 Tab 缩进,原因是在 Code Style > Go 的  Other 中有项 Run gofmt [] On code reformat, 这项也不能勾选。

不明白 go fmtgofmt 为何强势而无理的用 Tab 进行缩进,看到多数地方以 8 个空格来显示一个  Tab,实在是难看,像下面这样子的

好了,言归正传到 Go 的系统标准库的使用

首先是反射的基本用法

Go 的每个 interface{} 有两个信息,分别是 <value, type>。反射可以用来修改指针指向的数据,首先用 Value.Elem() 获得指针的间接引用,只有 CanAddr() 和 CanSet() 的数据才是可更改的,还有就是只能对导出的字段(首字母大写的)才能修改

反射的其他用法,可以想像在别的语言(如  Java) 中反射能做什么,尝试下 Go 的反射是否能做类似的事情,比如可通过反射创建类型,reflect 的 Makeslice(), Makemap() 和 Makechan() 方法待。

unsafe 包,由名字所暗示的用它要小心,其中的 unsafe.Sizeof() 像 C/C++ 的 sizeof()  用来查看类型数据占用的空间很有用,但它对 slice 无效。

通过 uintptr 和 unsafePointer(类似 C 的 void*),  能够进行内存数据的危险操作。

排序的三个基本方法,在 sort.Interface 接口中定义的

Go 的排序方法不像 Java 的  Comparable 定义在元素上的,而是在集合上,[]int, []float64  和  []string 内建支持排序。我们可以看在  sort.go 中的 IntSlice 对 sort.Interface 的三个接口方法的实现

[]int, []float64, []string 原生支持并不是可以直接 sort 去对它们排序,而是在 sort.go 中实现了自定义类型 IntSlice, Float64Slice 和 StringSlice, 排序时还得转换成对应的类型,如 []int -> IntSlice。看起来 Go 对排序的设计有点笨拙。

还可用 sort.Slice() 函数进行排序,但它需要传递一个排序的回调函数。

os 包中许多函数对应的 shell 命令操作,

os.Args              返回命令行参数, go 的 main() 函数不带参数,用这个取
func Getwd(dir string, err error)
func Chdir(dir string) error
func Environ() []string    //得到所有环境变量
func Exit(code int)
func Create(name string)(file *File, err error)   //创建文件
func Open(name string)(file *File, err err)
func (f *File) Read(b []byte)(n int, err error)   // 读文件内容
func (f *File) WriteString(s string)(ret int, err error)  // 写文件
func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error)  //启动进程

Go 的控制台输入输出定义在 fmt 包中,有 Scan 和 Print 系列的函数,定义在 scan.go 和  print.go 中

flag 用来解析命令行参数,用 os.Args 得到的只是原始的数组。可支持 -flag, -flag=x, -flag x 这样的命令行参数输入形式。以及非 flag 的自由参数, non-flag 参数必须放在 flag 参数后,因为 flag 解析完 non-flag  的参数便 停止了,后面的  -flag 这样的参数得不到解析

flag 的例子

$ go run test.go -profile saml -verbose abc xyz
profile: saml, verbose: true, others: [abc xyz]

还有更强大的命令行参数解析库,https://github.com/spf13/cobra

os 包提供了一些文件/目录的创建删除,以及读写内容的操作,io 包最重要的是 Reader 和 Writer 两个接口。如果读写文件总是一个个字节进行,效率势必低下,所以需要缓冲(buffer)。

下面尝试用一个 32 字节的缓冲区来读入文件内容

更简单的方法是用 bufio.NewReader(file) 和 ioutil 包的 ReadAll(), ReadFile(), WriteFile(), ReadDir() 操作。如

或者

Go 提供有 log 日志包,最简单的用法是

log.Println("message")

输出为

2021/08/14 13:29:38 message

可通过配置输出日志到文件中,并设定日期格式,日志输出前缀,记录代码文件名和行号等,不展开了。

本文链接 https://yanbin.blog/go-language-notes-4/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments