随机数
代码实例
// Go 的 `math/rand` 包提供了[伪随机数生成器(英)](http://en./wiki/Pseudorandom_number_generator)。
package main
import "fmt"
import "math/rand"
func main() {
// 例如,`rand.Intn` 返回一个随机的整数 n,`0 <= n <= 100`。
fmt.Print(rand.Intn(100), ",")
fmt.Print(rand.Intn(100))
fmt.Println()
// `rand.Float64` 返回一个64位浮点数 `f`,
// `0.0 <= f <= 1.0`。
fmt.Println(rand.Float64())
// 这个技巧可以用来生成其他范围的随机浮点数,例如
// `5.0 <= f <= 10.0`
fmt.Print((rand.Float64()*5)+5, ",")
fmt.Print((rand.Float64() * 5) + 5)
fmt.Println()
// 要让伪随机数生成器有确定性,可以给它一个明确的种子。
s1 := rand.NewSource(42)
r1 := rand.New(s1)
// 调用上面返回的 `rand.Source` 的函数和调用 `rand` 包中函数
// 是相同的。
fmt.Print(r1.Intn(100), ",")
fmt.Print(r1.Intn(100))
fmt.Println()
// 如果使用相同的种子生成的随机数生成器,将会产生相同的随机
// 数序列。
s2 := rand.NewSource(42)
r2 := rand.New(s2)
fmt.Print(r2.Intn(100), ",")
fmt.Print(r2.Intn(100))
fmt.Println()
}
运行程序
$ go run random-numbers.go
81,87
0.6645600532184904
7.123187485356329,8.434115364335547
5,87
5,87
# 参阅 [`math/rand`](http:///pkg/math/rand/) 包
# 文档,提供了 Go 可以提供的其他随量的参考信息。
数字解析
代码实例
// 从字符串中解析数字在很多程序中是一个基础常见的任务,在
// Go 中是这样处理的。
package main
// 内置的 `strconv` 包提供了数字解析功能。
import "strconv"
import "fmt"
func main() {
// 使用 `ParseFloat` 解析浮点数,这里的 `64` 表示表示解
// 析的数的位数。
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)
// 在使用 `ParseInt` 解析整形数时,例子中的参数 `0` 表
// 示自动推断字符串所表示的数字的进制。`64` 表示返回的
// 整形数是以 64 位存储的。
i, _ := strconv.ParseInt("123", 0, 64)
fmt.Println(i)
// `ParseInt` 会自动识别出十六进制数。
d, _ := strconv.ParseInt("0x1c8", 0, 64)
fmt.Println(d)
// `ParseUint` 也是可用的。
u, _ := strconv.ParseUint("789", 0, 64)
fmt.Println(u)
// `Atoi` 是一个基础的 10 进制整型数转换函数。
k, _ := strconv.Atoi("135")
fmt.Println(k)
// 在输入错误时,解析函数会返回一个错误。
_, e := strconv.Atoi("wat")
fmt.Println(e)
}
运行程序
$ go run number-parsing.go
1.234
123
456
789
135
strconv.ParseInt: parsing "wat": invalid syntax
# 下面我们将了解一下另一个常见的解析任务:URL 解析。
URL解析
代码实例
// URL 提供了一个[统一资源定位方式](http://adam./past/2010/3/30/urls_are_the_uniform_way_to_locate_resources/)。
// 这里了解一下 Go 中是如何解析 URL 的。
package main
import "fmt"
import "net/url"
import "strings"
func main() {
// 我们将解析这个 URL 示例,它包含了一个 scheme,
// 认证信息,主机名,端口,路径,查询参数和片段。
s := "postgres://user:pass@host.com:5432/path?k=v#f"
// 解析这个 URL 并确保解析没有出错。
u, err := url.Parse(s)
if err != nil {
panic(err)
}
// 直接访问 scheme。
fmt.Println(u.Scheme)
// `User` 包含了所有的认证信息,这里调用 `Username`
// 和 `Password` 来获取独立值。
fmt.Println(u.User)
fmt.Println(u.User.Username())
p, _ := u.User.Password()
fmt.Println(p)
// `Host` 同时包括主机名和端口信息,如过端口存在的话,
// 使用 `strings.Split()` 从 `Host` 中手动提取端口。
fmt.Println(u.Host)
h := strings.Split(u.Host, ":")
fmt.Println(h[0])
fmt.Println(h[1])
// 这里我们提出路径和查询片段信息。
fmt.Println(u.Path)
fmt.Println(u.Fragment)
// 要得到字符串中的 `k=v` 这种格式的查询参数,可以使
// 用 `RawQuery` 函数。你也可以将查询参数解析为一个
// map。已解析的查询参数 map 以查询字符串为键,对应
// 值字符串切片为值,所以如何只想得到一个键对应的第
// 一个值,将索引位置设置为 `[0]` 就行了。
fmt.Println(u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
fmt.Println(m["k"][0])
}
运行程序
# 运行我们的 URL 解析程序,显示全部我们提取的 URL 的
# 不同数据块。
$ go run url-parsing.go
postgres
user:pass
user
pass
host.com:5432
host.com
5432
/path
f
k=v
map[k:[v]]
v