go语言相关库和函数
1、fmt 包
Go 语言标准库中的 fmt 包提供了打印函数将数据以字符串形式输出到控制台、文件、其他满足 io.Writer 接口的至以及其他字符串中
2、io/ioutil 包
跟操作文件、文件夹相关的函数
3、go语言nil
在Go语言中,布尔类型的零值(初始值)为 false,数值类型的零值为 0,字符串类型的零值为空字符串
""
,而指针、切片、映射、通道、函数和接口的零值则是 nilnil 是Go语言中一个预定义好的标识符,有过其他编程语言开发经验的开发者也许会把 nil 看作其他语言中的 null(NULL),其实这并不是完全正确的,因为Go语言中的 nil 和其他语言中的 null 有很多不同点
- nil 标识符是不能比较的
- nil 不是关键字或保留字
- nil 没有默认类型
- 不同类型 nil 的指针是一样的
- 不同类型的 nil 是不能比较的,两个相同类型的 nil 值也可能无法比较
- 不同类型的 nil 值占用的内存大小可能是不一样的
4、Go语言读取文件的几种方式
①使用
ioutil
直接读取//从一个io.Reader类型中读取内容直到返回错误或者EOF时返回读取的数据,当err == nil时,数据成功读取到[]byte中 //ReadAll函数被定义为从源中读取数据直到EOF,它是不会去从返回数据中去判断EOF来作为读取成功的依据 func ReadAll(r io.Reader) ([]byte, error) //读取一个目录,并返回一个当前目录下的文件对象列表和错误信息 func ReadDir(dirname string) ([]os.FileInfo, error) //读取文件内容,并返回[]byte数据和错误信息。err == nil时,读取成功 func ReadFile(filename string) ([]byte, error)
②借助
os.Open
进行读取文件由于
os.Open
是打开一个文件并返回一个文件对象,因此其实可以结合ioutil.ReadAll(r io.Reader)
来进行读取。io.Reader
其实是一个包含Read
方法的接口类型,而文件对象本身是实现了了Read
方法的。//打开一个需要被读取的文件,如果成功读取,返回的文件对象将可用被读取,该函数默认的权限为O_RDONLY,也就是只对文件有只读权限。如果有错误,将返回*PathError类型 func Open(name string) (*File, error) //大部分用户会选择该函数来代替Open or Create函数。该函数主要用来指定参数(os.O_APPEND|os.O_CREATE|os.O_WRONLY)以及文件权限(0666)来打开文件,如果打开成功返回的文件对象将被用作I/O操作 func OpenFile(name string, flag int, perm FileMode) (*File, error)
③使用
os.Open
和bufio.Reader
读取文件内容
bufio
包实现了缓存IO,它本身包装了io.Reader
和io.Writer
对象,创建了另外的Reader和Writer对象,不过该种方式是带有 缓存的,因此对于文本I/O来说,该包是提供了一些便利的//首先定义了一个用来缓冲io.Reader对象的结构体,同时该结构体拥有以下相关的方法 type Reader struct { } //NewReader函数用来返回一个默认大小buffer的Reader对象(默认大小好像是4096) 等同于NewReaderSize(rd,4096) func NewReader(rd io.Reader) *Reader //该函数返回一个指定大小buffer(size最小为16)的Reader对象,如果 io.Reader参数已经是一个足够大的Reader,它将返回该Reader func NewReaderSize(rd io.Reader, size int) *Reader //该方法返回从当前buffer中能被读到的字节数 func (b *Reader) Buffered() int //Discard方法跳过后续的 n 个字节的数据,返回跳过的字节数。如果0 <= n <= b.Buffered(),该方法将不会从io.Reader中成功读取数据。 func (b *Reader) Discard(n int) (discarded int, err error) //Peekf方法返回缓存的一个切片,该切片只包含缓存中的前n个字节的数据 func (b *Reader) Peek(n int) ([]byte, error) //把Reader缓存对象中的数据读入到[]byte类型的p中,并返回读取的字节数。读取成功,err将返回空值 func (b *Reader) Read(p []byte) (n int, err error) //返回单个字节,如果没有数据返回err func (b *Reader) ReadByte() (byte, error) //该方法在b中读取delimz之前的所有数据,返回的切片是已读出的数据的引用,切片中的数据在下一次的读取操作之前是有效的。如果未找到delim,将返回查找结果并返回nil空值。因为缓存的数据可能被下一次的读写操作修改,因此一般使用ReadBytes或者ReadString,他们返回的都是数据拷贝 func (b *Reader) ReadSlice(delim byte) (line []byte, err error) //功能同ReadSlice,返回数据的拷贝 func (b *Reader) ReadBytes(delim byte) ([]byte, error) //功能同ReadBytes,返回字符串 func (b *Reader) ReadString(delim byte) (string, error) //该方法是一个低水平的读取方式,一般建议使用ReadBytes('\n') 或 ReadString('\n'),或者使用一个 Scanner来代替。ReadLine 通过调用 ReadSlice 方法实现,返回的也是缓存的切片,用于读取一行数据,不包括行尾标记(\n 或 \r\n) func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) //读取单个UTF-8字符并返回一个rune和字节大小 func (b *Reader) ReadRune() (r rune, size int, err error)
5、go语言文件操作
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
权限位0644func Create(name string) (file *File, err error)
权限位0666
6、make和new
Go语言中的内建函数new和make是两个用于内存分配的原语(allocation primitives)。对于初学者,这两者的区别也挺容易让人迷糊的。简单的说,new只分配内存,make用于slice,map,和channel的初始化。
7、defer
Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题。
如下代码所示,我们一般写打开一个资源是这样操作的:
func ReadWrite() bool { file.Open("file") // 做一些工作 if failureX { file.Close() return false } if failureY { file.Close() return false } file.Close() return true }
我们看到上面有很多重复的代码,Go的defer有效解决了这个问题。使用它后,不但代码量减少了很多,而且程序变得更优雅。在defer后指定的函数会在函数退出前调用。
func ReadWrite() bool { file.Open("file") defer file.Close() if failureX { return false } if failureY { return false } return true }
8、go语言的init()函数
init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量
init函数在main函数执行之前,自动被调用。不能被其他函数调用
每个包可以拥有多个init函数
9、go语言:秒、毫秒、纳秒时间戳输出
package main import ( "time" "fmt" ) func main() { fmt.Printf("时间戳(秒):%v;\n", time.Now().Unix()) fmt.Printf("时间戳(纳秒):%v;\n",time.Now().UnixNano()) fmt.Printf("时间戳(毫秒):%v;\n",time.Now().UnixNano() / 1e6) fmt.Printf("时间戳(纳秒转换为秒):%v;\n",time.Now().UnixNano() / 1e9) }