mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-11 19:41:43 +08:00
9.4
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
## 翻译进度
|
||||
|
||||
9.3 [锁和 sync 包](eBook/09.3.md)
|
||||
9.4 [精密计算和 big 包](eBook/09.4.md)
|
||||
|
||||
## 支持本书
|
||||
|
||||
|
@@ -1,15 +1,22 @@
|
||||
# 精密计算和 big 包
|
||||
|
||||
202
|
||||
我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用Go语言中的fload64类型进行浮点运算,返回结果将精确到15位,足以满足大多数的任务。当对超出in64或者uint64类型这样的大数进行计算时,如果对精度没有要求,float32或者float64可以胜任,但如果对精度有严格要求的时候,我们不能使用浮点数,在内存中它们只能被近似的表示。
|
||||
我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用 Go 语言中的 fload64 类型进行浮点运算,返回结果将精确到 15 位,足以满足大多数的任务。当对超出 int64 或者 uint64 类型这样的大数进行计算时,如果对精度没有要求,float32 或者 float64 可以胜任,但如果对精度有严格要求的时候,我们不能使用浮点数,在内存中它们只能被近似的表示。
|
||||
|
||||
对于整数的高精度计算Go语言中提供了big包。其中包含了math包:有用来表示大整数的big.Int和表示大有理数的big.Rat类型(可以表示为2/5或3.1416这样的分数,而不是无理数或π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。
|
||||
对于整数的高精度计算 Go 语言中提供了 big 包。其中包含了 math 包:有用来表示大整数的 `big.Int` 和表示大有理数的 `big.Rat` 类型(可以表示为 2/5 或 3.1416 这样的分数,而不是无理数或 π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。
|
||||
|
||||
大的整型数字是通过big.NewInt(n)来构造的,其中n位int64类型整数。而大有理数是用过big.NewRat(N,D)方法构造.N(分子)和D(分母)都是int64型整数。因为Go语言不支持运算符重载,所以所有大数字类型都有像是Add()和Mul()这样的方法。它们作用于作为receiver的整数和有理数,大多数情况下它们修改receiver并以receiver作为返回结果。因为没有必要创建big.Int类型的临时变量来存放中间结果,所以这样的运算可通过内存链式存储。
|
||||
大的整型数字是通过 `big.NewInt(n)` 来构造的,其中 n 位 int64 类型整数。而大有理数是用过 `big.NewRat(N,D)` 方法构造。N(分子)和 D(分母)都是 int64 型整数。因为 Go 语言不支持运算符重载,所以所有大数字类型都有像是 Add() 和 Mul() 这样的方法。它们作用于作为 receiver 的整数和有理数,大多数情况下它们修改 receiver 并以 receiver 作为返回结果。因为没有必要创建 big.Int 类型的临时变量来存放中间结果,所以这样的运算可通过内存链式存储。
|
||||
|
||||
示例 9.2 [big.go](examples/chapter_9/big.go)
|
||||
示例 9.2 [big.go](examples/chapter_9/big.go):
|
||||
|
||||
package main
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math""
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Here are some calculations with bigInts:
|
||||
im := big.NewInt(math.MaxInt64)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#B 自定义和外部包的使用,编译,测试,文档和安装
|
||||
#9.5 自定义包和可见性
|
||||
# 9.5 自定义包和可见性
|
||||
|
||||
203
|
||||
包是Go语言中代码组成和代码编译的主要方式。很多关于它们的基本信息已经在4.2章节中给出,最引人注目的便是可见性。现在我们来看看具体如何来使用自己写的包。在下一节,我们将回顾一些标准库中的包,自定义的包和标准库以外的包。
|
||||
|
||||
当写自己包的时候,要使用短小的不含有_(下划线)的小写单词来为文件命名。这里有个简单例子来说明包是如何相互调用以及可见性是如何实现的。
|
||||
@@ -12,47 +12,47 @@
|
||||
package pack1
|
||||
var Pack1Int int = 42
|
||||
var PackFloat = 3.14
|
||||
|
||||
|
||||
func ReturnStr() string {
|
||||
return "Hello main!"
|
||||
}
|
||||
|
||||
|
||||
它包含了一个整型变量PackInt和一个返回字符串的函数ReturnStr。这段程序在运行时不做任何的事情,因为它不包含有一个main函数。
|
||||
|
||||
在主程序pack_test.go中这个包通过声明的方式被导入
|
||||
|
||||
import “./pack1/pack1”
|
||||
import “./pack1/pack1”
|
||||
|
||||
import的一般格式如下:
|
||||
|
||||
import “包的路径或url地址“ 像 import "github.com/org1/pack1”
|
||||
|
||||
|
||||
路径是指当前目录的相对路径。
|
||||
|
||||
示例 9.5 [package_test.go](examples/chapter_9/package_test.go)
|
||||
|
||||
package main
|
||||
import (
|
||||
import (
|
||||
"fmt"
|
||||
"./pack1/pack1"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var test1 string
|
||||
var test1 string
|
||||
test1 = pack1.ReturnStr()
|
||||
fmt.Printf("ReturnStr from package1: %s\n", test1)
|
||||
fmt.Printf("ReturnStr from package1: %s\n", test1)
|
||||
fmt.Printf(“Integer from package1: %d\n”, pack1.Pack1Int)
|
||||
fmt.Printf(“Integer from package1: %d\n”, pack1.Pack1Int)
|
||||
// fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)
|
||||
|
||||
|
||||
输出结果:
|
||||
|
||||
输出结果:
|
||||
|
||||
|
||||
ReturnStr from package1: Hello main!
|
||||
Integer from package1: 42
|
||||
|
||||
|
||||
如果包pack1和我们的程序在统同一路径下,我们可以通过"import ./pack1"这样的方式来引入,但这不被视为一个好的方法。
|
||||
|
||||
|
||||
fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)这行代码试图访问一个未引用的变量或者函数,甚至没有编译。将会返回一个错误:
|
||||
|
||||
cannot refer to unexported name pack1.pack1Float
|
||||
@@ -75,7 +75,7 @@ pack1包只导入其副作用,只执行了它的init函数并初始化了其
|
||||
如果你要在你的应用中使用一个或多个外部包,首先你必须使用go install(参见9.7章节)在你的本地机器上安装它们。
|
||||
|
||||
假设你想使用http://codesite.ext/author/goExample/goex这种托管在googlecode, github,launchpad等代码网站上的包。
|
||||
导入外部安装包:
|
||||
|
||||
你可以通过如下命令安装
|
||||
|
||||
go install codesite.ext/author/goExample/goex
|
||||
@@ -103,7 +103,7 @@ init函数是不能被调用的。
|
||||
|
||||
在Linux/OSX下可以用类似4.3章节的Makefile脚本做到这一点:
|
||||
|
||||
编译并安装一个包(参见9.7章节):
|
||||
include $(GOROOT)/src/Make.inc
|
||||
TARG=pack1
|
||||
GOFILES=\
|
||||
pack1.go\
|
||||
@@ -132,8 +132,6 @@ go install(参见9.7章节,从Go1的首选方式)同样复制pack1.a到本地
|
||||
|
||||
练习:
|
||||
|
||||
当第13章我们遇到使用测试工具进行测试的时候我们将重新回到自己的包的制作和编译这个话题。
|
||||
问题9.1:
|
||||
|
||||
(a)一个包能分成多个源文件么?
|
||||
|
||||
问题9.1:
|
||||
|
@@ -77,6 +77,7 @@
|
||||
- 9.2 [regexp 包](09.2.md)
|
||||
- 9.3 [锁和 sync 包](09.3.md)
|
||||
- 9.4 [精密计算和 big 包](09.4.md)
|
||||
- 9.5 [自定义包和可见性](09.5.md)
|
||||
- 第10章:结构(struct)与方法(method)
|
||||
- 第11章:接口(interface)与反射(reflection)
|
||||
|
||||
|
Reference in New Issue
Block a user