Browse Month: 二月 2017

Go 标准库介绍二: time

介绍Go 标准库 time 常用导出函数,结构体及其方法。

time包提供显示和计算时间用的函数。

1. 时间处理类型

Go 中时间处理依赖的数据类型: time.Time, time.Month, time.Weekday, time.Duration, time.Location

1.1 time.Time 时间点

time.Time 代表一个纳秒精度的时间点.

/usr/local/go/src/time/time.go 定义如下:

时间变量标识一个具体的时间点,演示如下:

代码中应使用time.Time 类型值来保存和传递时间,而不能用指针。表示时间的变量和字段,应为time.Time类型,而不是*time.Time类型。

每一个时间点都具有时区信息,当计算时间的表示格式时,如FormatHourYear等方法,都会考虑该信息。LocalUTCIn方法返回一个指定时区(但指向同一时间点)的Time。修改时区信息只是会改变其表示,不会修改被表示的时间点。

1.2 time.Month 月份

time.Month 代表一年中的某个月

/usr/local/go/src/time/time.go 定义如下:

和月份相关的常量如下:

1.3 time.Weekday 星期

time.Weekday 代表一周的周几。

/usr/local/go/src/time/time.go 定义如下:

和星期相关的常量:

1.4 time.Duration 时间段

time.Duration 类型代表两个时间点之间经过的纳秒数,可表示的最长时间段约为290年。

/usr/local/go/src/time/time.go 定义如下:

涉及常量如下:

1.5 time.Location 时区

Location代表一个地点,以及该地点所在的时区信息。北京时间可以使用 Asia/Shanghai

/usr/local/go/src/time/zoneinfo.go 中定义:

预定义时区变量:

2. time.Time 方法

介绍 time.Time 接受者的方法:获取时间点,获取时间相关信息,时间比较,计算和序列化操作。

示例代码文件: $GOPATH/src/github.com/ironxu/go_note/library/time/time.go

2.1 获取一个时间的方法

  • func Now() Time {} // 当前本地时间
  • func Unix(sec int64, nsec int64) Time {} // 根据时间戳返回本地时间
  • func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {} // 返回指定时间

2.2 时间显示

  • func (t Time) UTC() Time {} // 获取指定时间在UTC 时区的时间表示
  • func (t Time) Local() Time {} // 以本地时区表示
  • func (t Time) In(loc *Location) Time {} // 时间在指定时区的表示
  • func (t Time) Format(layout string) string {} // 按指定格式显示时间

2.3 获取日期信息

  • func (t Time) Date() (year int, month Month, day int) {} // 返回时间的日期信息
  • func (t Time) Year() int {} // 返回年
  • func (t Time) Month() Month {} // 月
  • func (t Time) Day() int {} // 日
  • func (t Time) Weekday() Weekday {} // 星期
  • func (t Time) ISOWeek() (year, week int) {} // 返回年,星期范围编号
  • func (t Time) Clock() (hour, min, sec int) {} // 返回时间的时分秒
  • func (t Time) Hour() int {} // 返回小时
  • func (t Time) Minute() int {} // 分钟
  • func (t Time) Second() int {} // 秒
  • func (t Time) Nanosecond() int {} // 纳秒
  • func (t Time) YearDay() int {} // 一年中对应的天
  • func (t Time) Location() *Location {} // 时间的时区
  • func (t Time) Zone() (name string, offset int) {} // 时间所在时区的规范名和想对UTC 时间偏移量
  • func (t Time) Unix() int64 {} // 时间转为时间戳
  • func (t Time) UnixNano() int64 {} // 时间转为时间戳(纳秒)

2.4 时间比较与计算

  • func (t Time) IsZero() bool {} // 是否是零时时间
  • func (t Time) After(u Time) bool {} // 时间在u 之前
  • func (t Time) Before(u Time) bool {} // 时间在u 之后
  • func (t Time) Equal(u Time) bool {} // 时间与u 相同
  • func (t Time) Add(d Duration) Time {} // 返回t +d 的时间点
  • func (t Time) Sub(u Time) Duration {} // 返回 t-u
  • func (t Time) AddDate(years int, months int, days int) Time {} 返回增加了给出的年份、月份和天数的时间点Time

2.6 时间序列化

  • func (t Time) MarshalBinary() ([]byte, error) {} // 时间序列化
  • func (t Time) UnmarshalBinary(data []byte) error {} // 反序列化
  • func (t Time) MarshalJSON() ([]byte, error) {} // 时间序列化
  • func (t Time) MarshalText() ([]byte, error) {} // 时间序列化
  • func (t Time) GobEncode() ([]byte, error) {} // 时间序列化
  • func (t Time) GobDecode() ([]byte, error) {} // 时间序列化

3. time.Duration 方法

介绍 time.Duration 时间段接受者的方法:输出和改变时间段单位。

  • func (d Duration) String() string // 格式化输出 Duration
  • func (d Duration) Nanoseconds() int64 // 将时间段表示为纳秒
  • func (d Duration) Seconds() float64 // 将时间段表示为秒
  • func (d Duration) Minutes() float64 // 将时间段表示为分钟
  • func (d Duration) Hours() float64 // 将时间段表示为小时

4. time.Location 方法

time.Location 时区的导出函数

  • func (l *Location) String() string // 输出时区名
  • func FixedZone(name string, offset int) *Location // FixedZone 使用给定的地点名name和时间偏移量offset(单位秒)创建并返回一个Location
  • func LoadLocation(name string) (*Location, error) // LoadLocation 使用给定的名字创建Location

5. 其他方法

  • func Sleep(d Duration) // Sleep阻塞当前go程至少d代表的时间段。d<=0时,Sleep会立刻返回

参考资料

可以关注我的微博了解更多信息: @刚刚小码农

Go 标准库介绍一: strings

本文介绍Go 标准库 strings 常用导出函数,结构体及其方法。

strings 包实现了用于操作字符串的简单函数,包括 strings 导出函数和 Reader, Replacer 两个结构体。

1. strings 常用导出函数

判断字符串与子串关系

  • func EqualFold(s, t string) bool // 判断两个utf-8编码字符串,大小写不敏感
  • func HasPrefix(s, prefix string) bool // 判断s是否有前缀字符串prefix
  • func Contains(s, substr string) bool // 判断字符串s是否包含子串substr
  • func ContainsAny(s, chars string) bool // 判断字符串s是否包含字符串chars中的任一字符
  • func Count(s, sep string) int // 返回字符串s中有几个不重复的sep子串

获取字符串中子串位置

  • func Index(s, sep string) int // 子串sep在字符串s中第一次出现的位置,不存在则返回-1
  • func IndexByte(s string, c byte) int // 字符c在s中第一次出现的位置,不存在则返回-
  • func IndexAny(s, chars string) int // 字符串chars中的任一utf-8码值在s中第一次出现的位置,如果不存在或者chars为空字符串则返回-1
  • func IndexFunc(s string, f func(rune) bool) int // s中第一个满足函数f的位置i(该处的utf-8码值r满足f(r)==true),不存在则返回-1
  • func LastIndex(s, sep string) int // 子串sep在字符串s中最后一次出现的位置,不存在则返回-1

字符串中字符处理

  • func Title(s string) string // 返回s中每个单词的首字母都改为标题格式的字符串拷贝
  • func ToLower(s string) string // 返回将所有字母都转为对应的小写版本的拷贝
  • func ToUpper(s string) string // 返回将所有字母都转为对应的大写版本的拷贝
  • func Repeat(s string, count int) string // 返回count个s串联的字符串
  • func Replace(s, old, new string, n int) string // 返回将s中前n个不重叠old子串都替换为new的新字符串,如果n<0会替换所有old子串
  • func Map(mapping func(rune) rune, s string) string // 将s的每一个unicode码值r都替换为mapping(r),返回这些新码值组成的字符串拷贝。如果mapping返回一个负值,将会丢弃该码值而不会被替换

字符串前后端处理

  • func Trim(s string, cutset string) string // 返回将s前后端所有cutset包含的utf-8码值都去掉的字符串
  • func TrimSpace(s string) string // 返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串
  • func TrimFunc(s string, f func(rune) bool) string // 返回将s前后端所有满足f的unicode码值都去掉的字符串

字符串分割与合并

  • func Fields(s string) []string // 返回将字符串按照空白(通过unicode.IsSpace判断,可以是一到多个连续的空白字符)分割的多个字符串
  • func Split(s, sep string) []string // 用去掉s中出现的sep的方式进行分割,会分割到结尾,并返回生成的所有片段组成的切片
  • func Join(a []string, sep string) string // 将一系列字符串连接为一个字符串,之间用sep来分隔

strings 导出函数示例

$GOPATH/src/github.com/ironxu/go_note/library/strings/strings.go 源码如下:

2. Reader 结构体

Reader 类型从一个字符串读取数据,实现了io.Reader, io.Seeker等接口。

  • func NewReader(s string) *Reader // 通过字符串 s 创建一个 Reader
  • func (r *Reader) Len() int // 返回 r 还没有读取部分的长度
  • func (r *Reader) Read(b []byte) (n int, err error) // 读取部分数据到 b 中,读取的长度取决于 b 的容量
  • func (r *Reader) ReadByte() (b byte, err error) // 从 r 中读取一字节数据

$GOPATH/src/github.com/ironxu/go_note/library/strings/reader.go 源码如下:

3. Replacer 结构体

Replacer 类型实现字符串替换的操作

  • func NewReplacer(oldnew ...string) *Replacer // 使用提供的多组old、new字符串对创建一个*Replacer
  • func (r *Replacer) Replace(s string) string // 返回s 所有替换完后的拷贝
  • func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error) // 向w中写入s替换完后的拷贝

$GOPATH/src/github.com/ironxu/go_note/library/strings/replace.go 源码如下:

参考

可以关注我的微博了解更多信息: @刚刚小码农

Go 之旅五: 并发

本文是学习 A Tour of Go (中文参考 Go 之旅中文 ) 整理的笔记。介绍Go 语言线程,信道以及互斥锁的概念和使用方法。

1. Go 线程

$GOPATH/src/go_note/gotour/concurrency/goroutine/goroutine.go 源码如下

Go 线程(goroutine)是由Go 运行时管理的轻量级线程。

会启动一个新的 Go 线程程并执行

其中 fxyz 的求值在当前的 Go 线程中进行,而 f 的执行发生在新的 Go 线程中。

Go 程在相同的地址空间中运行,因此在访问共享的内存时必须进行同步,这可以通过使用sync 包或信道实现。

2. 信道

$GOPATH/src/go_note/gotour/concurrency/channel/channel.go 源码如下

信道是带有类型的管道,通过信道操作符 <- 来从信道发送或者接收值。

“箭头”就是数据流的方向。

信道在使用前必须创建:

默认情况下,发送和接收操作在另一端准备好之前都会阻塞。这使得 Go 程可以在没有显式的锁或竞态变量的情况下进行同步。

2.1 带缓冲的信道

信道可以是带缓冲的, 将缓冲长度作为第二个参数提供给 make 来初始化一个带缓冲的信道:

仅当信道的缓冲区填满后,向其发送数据时才会阻塞。当缓冲区为空时,接受方会阻塞。

2.2 range 和 close

发送者可通过 close 关闭一个信道来表示没有需要发送的值。接收者可以通过为接收表达式的第二个参数来测试信道是否被关闭:若没有值可以接收且信道已被关闭,该值为 false

循环 for i := range c 会不断从信道接收值,直到它被关闭。

注意: 只有发送者才能关闭信道,而接收者不能。向一个已经关闭的信道发送数据会引发程序错误。信道与文件不同,通常情况下无需关闭它们。只有在必须告诉接收者不再有值需要发送的时候才有必要关闭,如终止一个 range 循环。

3. select 语句

$GOPATH/src/go_note/gotour/concurrency/select/select.go 源码如下:

select 语句使一个 Go 线程可以等待多个通信操作。

select 会阻塞到某个分支可以继续执行为止,这时就会执行该分支。当多个分支都准备好时会随机选择一个执行。

select 中的其它分支都没有准备好时,default 分支就会执行。为了在尝试发送或者接收时不发生阻塞,可使用 default 分支

4. sync.Mutex

$GOPATH/src/go_note/gotour/concurrency/mutex/mutex.go 源码如下:

互斥(mutual exclusion),指一次只有一个 Go 线程能够访问一个共享的变量。一般使用互斥锁(Mutex)来提供这种机制。

Go 标准库中提供了 sync.Mutex 互斥锁类型及其两个方法:

通过在代码前调用 Lock() 方法,在代码后调用 Unlock() 方法来保证一段代码的互斥执行。另外可以用 defer 语句来保证互斥锁一定会被解锁。

参考

可以关注我的微博了解更多信息: @刚刚小码农