这是我的Go学习的第六篇笔记,也是Go入门的最后一篇笔记。在大多数语言中,了解了变量和数据类型,流程控制,函数,面向对象,再加上标准库,就可以用这门语言去写一些项目了。
首先让我想想,在工作中通常会用语言频繁处理什么问题或者处理什么数据?最常见的应该是各种字符串操作,日期和时间,读写文件、socket等IO相关的操作!
字符串处理 — Strings
String提供了一组处理字符串的操作,常用的有:
1. 判断一个字符串是否在另一个字符串中
2. 分割字符串为[]string和组合[]string为一个字符串
3. 字符串替换
4. …
太多了,就不一一列举了,这里列出一些常用的字符串操作。
字符串判断
// 判断子串substr是否在s中 func Contains(s, substr string) bool
字符串分割与合并
// 根据sep将字符串分割成一个数组 func Split(s, sep string) []string // 将数组a用sep拼接成一个字符串 func Join(a []string, sep string) string
字符串转换
// 转换成大写 func ToUpper(s string) string // 转换成小写 func ToLower(s string) string
字符串清理
// 去除首尾的cut字符串 func Trim(s string, cut string) string // 去除左侧的cut字符串 func TrimLeft(s string, cut string) string // 去除右侧的cut字符串 func TrimRight(s string, cut string) string
字符串替换
// s字符串中的将old替换成new,替换n次,n<0不限制替换次数 func Replace(s string, old string, new string, n int) string
IO操作——fmt、os、ioutil
Go语言io操作涉及到不止一个包。
终端的输入输出 – fmt
// 格式化输入 空格作为分隔符 func Scanf(format string, a ...interface{}) // 从终端获取输入,存入参数中,空格和换行作为分隔 func Scan(a ...interface{}) // 从终端获取输入,存入参数,空格作为分隔,遇到换行结束 func Scanln(a ...interface{}) // 格式化输出 func Printf(format string, a ...interface{}) func Println(s string) // 格式化字符串 func Sprintf(format string, a ...interface{}) string
文件读写 – os,ioutil
文件读写使用的是os包。Go提供了两个常见的打开模式,一个是只读模式,一个是只写模式,如下
// 只读打开文件,内部使用的是OpenFile并以只读的方式打开 func Open(name string) (*File, error) // 只写模式打开文件,将会清空内容 func Create(name string) (*File, error)
更多的操作需要使用OpenFile来操作,OpenFile定义如下:
OpenFile(name string, flag int, perm FileMode) (*File, error)
其中flag可以是下面常量的任意组合,含义如下:
// 打开方式,必须要指定 O_RDONLY 只读模式 O_WRONLY 只写模式 O_RDWR 读写模式 // 打开行为,和上面的组合使用 O_APPEND 以追加方式打开文件,写入的数据将追加到文件尾。 O_CREATE 当文件不存在时创建文件。 O_EXCL 与 O_CREATE 一起使用,当文件已经存在时 Open 操作失败。 O_SYNC 以同步方式打开文件。每次 write 系统调用后都等待实际的物理 I/O 完成后才返回,默认(不使用该标记)是使用缓冲的,也就是说每次的写操作是写到系统内核缓冲区中,等系统缓冲区满后才写到实际存储设备。 O_TRUNC 如果文件已存在,打开时将会清空文件内容。必须于 O_WRONLY 或 O_RDWR 配合使用。截断文件,需要有写的权限。
以追加方式打开一个文件的方法在os包里面没有直接提供,我们可以尝试自己写一个,如下:
// OpenAppend 以追加写入的方式打开一个文件,不存在将会创建 func OpenAppend(name string) (*os.File, error) { return os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)}
读写文件
将文件打开之后,接下来就是文件的读写。Go提供了一个ioutil应付简单的文件读写,ioutil是对os中文件读写的封装。文件读写方法如下(在iotuil包下)
// 读文件 func ReadFile(filename string) ([]byte, error) // 写入文件 func WriteFile(filename string, data []byte, perm os.FileMode) error
日期和时间库
在程序里面,获取日期和时间,休眠n秒是一个非常高频的场景。Go里面提供了time包用于时间的获取。
// unix时间戳,先调用time.Now()生成当前时间对象 func Unix() int64 // unix纳秒时间戳 func UnixNano() int64 // 格式化日期 func Format() string // 休眠一段时间,注意参数是纳秒 func Sleep(d Duration)
调用例子,打印当前unix时间戳
fmt.Println(time.Now().Unix())
格式化日志相对其他语言比较特殊,其中的layout是一个固定的日期:2006-01-02T15:04:05Z07:00,比如y-m-d H:i:s用这个表示就是2006-01-02 15:04:05。这个其实就是1234567这几个数字,对于这个日期是怎么来的感兴趣的话可以网上搜索一下。总体来说还是比较好记的。
以比较常见的日期格式格式化当前日期,例子如下
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
例子,休眠1秒
time.Sleep(1 * time.Second)
附:这里有一些常见的格式参考
ANSIC = "Mon Jan _2 15:04:05 2006" UnixDate = "Mon Jan _2 15:04:05 MST 2006" RubyDate = "Mon Jan 02 15:04:05 -0700 2006" RFC822 = "02 Jan 06 15:04 MST" RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone RFC850 = "Monday, 02-Jan-06 15:04:05 MST" RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone RFC3339 = "2006-01-02T15:04:05Z07:00" RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" Kitchen = "3:04PM" // Handy time stamps. Stamp = "Jan _2 15:04:05" StampMilli = "Jan _2 15:04:05.000" StampMicro = "Jan _2 15:04:05.000000" StampNano = "Jan _2 15:04:05.000000000"
文件路径操作 —— path
path提供了路径的常见操作。
// 返回文件的扩展名 func Ext(path string) string // 返回文件名 func Base(path string) string // 返回文件目录 func Dir(path string) string
需要注意的是这些操作都不会检测文件是否会存在,都是普通的字符串操作。
正则 — regexp
Go的正则包为regexp。这里不讨论如何写正则表达式,只说明go的正则包要怎么使用。
正则匹配
所用到的方法有
// 编译正则表达式,使用perl正则语法 Compile(expr string) (*Regexp, error) // 查找匹配项,匹配前n项,如果n小于0则匹配所有 func (re *Regexp) FindAllString(s string, n int) []string func (re *Regexp) FindAll(b []byte, n int) [][]byte // 匹配子串,匹配前n项,如果n<0则匹配所有 func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]stringfunc (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte
举个例子,匹配数字
r, err := regexp.Compile(`[0-9]`) res := r.FindAllString("1234hello", -1) // 如果等待匹配的是byte类型,则使用 r.FindAll() // 输出 // [1234]
如果需要匹配子组(正则表达式有括号的情况),则需要用FindAllStringSubmatch
r1, _ := regexp.Compile(`h([0-9]+)`) res1 := r1.FindAllStringSubmatch("h1234hah12", -1) // 如果等待匹配的是byte类型,则使用 r.FindAllSubmatch() fmt.Println(res1) // 输出 // [[h1234 1234] [h12 12]]