Merge remote-tracking branch 'bob/master'

This commit is contained in:
dake
2015-10-27 22:44:50 +08:00
14 changed files with 99 additions and 27 deletions

View File

@@ -474,7 +474,7 @@ var ch byte = 65 或 var ch byte = '\x41'
`\x` 总是紧跟着长度为 2 的 16 进制数)
另外一种可能的写法是 `\` 后面紧跟着长度为 3 的进制数,例如:`\377`
另外一种可能的写法是 `\` 后面紧跟着长度为 3 的进制数,例如:`\377`
不过 Go 同样支持 UnicodeUTF-8因此字符同样称为 Unicode 代码点或者 runes并在内存中使用 int 来表示。在文档中,一般使用格式 U+hhhh 来表示,其中 h 表示一个 16 进制数。其实 `rune` 也是 Go 当中的一个类型,并且是 `int32` 的别名。

View File

@@ -27,14 +27,14 @@ package main
import "fmt"
func main() {
x := Min(1, 3, 2, 0)
x := min(1, 3, 2, 0)
fmt.Printf("The minimum is: %d\n", x)
arr := []int{7,9,3,5,1}
x = Min(arr...)
x = min(arr...)
fmt.Printf("The minimum in the array arr is: %d", x)
}
func Min(a ...int) int {
func min(a ...int) int {
if len(a)==0 {
return 0
}

View File

@@ -11,17 +11,17 @@ package main
import "fmt"
func main() {
Function1()
function1()
}
func Function1() {
fmt.Printf("In Function1 at the top\n")
defer Function2()
fmt.Printf("In Function1 at the bottom!\n")
func function1() {
fmt.Printf("In function1 at the top\n")
defer function2()
fmt.Printf("In function1 at the bottom!\n")
}
func Function2() {
fmt.Printf("Function2: Deferred until the end of the calling function!")
func function2() {
fmt.Printf("function2: Deferred until the end of the calling function!")
}
```

View File

@@ -121,7 +121,7 @@ func sum(a []int) int {
return s
}
func main {
func main() {
var arr = [5]int{0, 1, 2, 3, 4}
sum(arr[:])
}
@@ -226,7 +226,7 @@ v := make([]int, 10, 50)
这样分配一个有 50 int 值的数组并且创建了一个长度为 10容量为 50 切片 v 切片 指向数组的前 10 个元素
**问题 7.3** 给定 `s := make([]byte, 5)`len(s) cap(s) 分别是多少`s = s[2:4]`len(s) cap(s) 又分别是多少
**问题 7.4** 假设 `s1 := []byte{'p', 'o', 'e', 'm'}` `s2 := d[2:]`s2 的值是多少如果我们执行 `s2[1] == 't'`s1 s2 现在的值又分是多少
**问题 7.4** 假设 `s1 := []byte{'p', 'o', 'e', 'm'}` `s2 := s1[2:]`s2 的值是多少如果我们执行 `s2[1] = 't'`s1 s2 现在的值又分是多少
## 7.2.5 多维 切片

View File

@@ -44,7 +44,7 @@ func AppendByte(slice []byte, data ...byte) []byte {
}
```
`func copy(dst, src []T) int` copy 方法将类型为 T 的切片从源地址 src 拷贝到目标地址 dst覆盖 dst 的相关元素,并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是 src 和 dst 的长度最小值。如果 src 是字符串那么元素类型就是 byte。如果你还想继续使用 src在拷贝技术后执行 `src = dst`
`func copy(dst, src []T) int` copy 方法将类型为 T 的切片从源地址 src 拷贝到目标地址 dst覆盖 dst 的相关元素,并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是 src 和 dst 的长度最小值。如果 src 是字符串那么元素类型就是 byte。如果你还想继续使用 src在拷贝结束后执行 `src = dst`
**练习 7.9**

View File

@@ -27,7 +27,7 @@ map 也可以用函数作为自己的值,这样就可以用来做分支结构
key1 对应的值可以通过赋值符号来设置为 `val1map1[key1] = val1`。
令 `v: = map1[key1]` 可以将 key1 对应的值赋值为 v如果 map 中没有 key1 存在,那么 v 将被赋值为 map1 的值类型的空值。
令 `v := map1[key1]` 可以将 key1 对应的值赋值为 v如果 map 中没有 key1 存在,那么 v 将被赋值为 map1 的值类型的空值。
常用的 `len(map1)` 方法可以获得 map 中的 pair 数目,这个数目是可以伸缩的,因为 map-pairs 在运行时可以动态添加和删除。

View File

@@ -53,7 +53,7 @@ func main() {
但是如果你想要一个排序的列表你最好使用结构体切片,这样会更有效:
```go
type struct {
type name struct {
key string
value int
}

View File

@@ -26,7 +26,6 @@ func main() {
for k, v := range invMap {
fmt.Printf("Key: %v, Value: %v / ", k, v)
}
fmt.Println()
}
```

0
eBook/09.5.md Executable file → Normal file
View File

0
eBook/09.8.md Executable file → Normal file
View File

View File

@@ -7,7 +7,11 @@ Go 开发者不需要写代码来释放程序中不再使用的变量和结构
如果想知道当前的内存状态,可以使用:
```go
fmt.Printf("%d\n", runtime.MemStats.Alloc/1024)
// fmt.Printf("%d\n", runtime.MemStats.Alloc/1024)
// 此处代码在 Go 1.5.1下不再有效,更正为
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d Kb\n", m.Alloc / 1024)
```
上面的程序会给出已分配内存的总量,单位是 Kb。进一步的测量参考 [文档页面](http://golang.org/pkg/runtime/#MemStatsType)。
@@ -30,4 +34,4 @@ runtime.SetFinalizer(obj, func(obj *typeObj))
- [目录](directory.md)
- 上一节:[类型的 String() 方法和格式化描述符](10.7.md)
- 下一章:[接口Interfaces与反射reflection](11.0.md)
- 下一章:[接口Interfaces与反射reflection](11.0.md)

68
eBook/11.11.md Normal file
View File

@@ -0,0 +1,68 @@
# 11.11 Printf和反射
在Go语言的标准库中前几节所述的反射的功能被大量地使用。举个例子fmt包中的Printf(以及其他格式化输出函数)都会使用反射来分析它的`...`参数。
Printf的函数声明为
```go
func Printf(format string, args ... interface{}) (n int, err error)
```
Printf中的`...`参数为空接口类型。Printf使用反射包来解析这个参数列表。所以Printf能够知道它每个参数的类型。因此格式化字符串中只有%d而没有%u和%ld因为它知道这个参数是unsigned还是long。这也是为什么Print和Println在没有格式字符串的情况下还能如此漂亮地输出。
为了让大家更加具体地了解Printf中的反射我们实现了一个简单的通用输出函数。其中使用了type-switch来推导参数类型并根据类型来输出每个参数的值(这里用了10.7节中练习10.13的部分代码)
示例 11.15 print.go:
```go
// print.go
package main
import (
"os"
"strconv"
)
type Stringer interface {
String() string
}
type Celsius float64
func (c Celsius) String() string {
return strconv.FormatFloat(float64(c),'f', 1, 64) + " °C"
}
type Day int
var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
func (day Day) String() string {
return dayName[day]
}
func print(args ...interface{}) {
for i, arg := range args {
if i > 0 {os.Stdout.WriteString(" ")}
switch a := arg.(type) { // type switch
case Stringer: os.Stdout.WriteString(a.String())
case int: os.Stdout.WriteString(strconv.Itoa(a))
case string: os.Stdout.WriteString(a)
// more types
default: os.Stdout.WriteString("???")
}
}
}
func main() {
print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C
}
// Tuesday was 18.4 °C
```
在12.8节中我们将阐释fmt.Fprintf()是怎么运用同样的反射原则的。
## 链接
- [目录](directory.md)
- 上一节:[反射包](11.10.md)
- 下一节:[接口和动态类型](11.12.md)

79
eBook/12.6.md Normal file
View File

@@ -0,0 +1,79 @@
# 用切片读写文件
切片提供了标准的Go方法来处理I/O缓冲下面`cat`函数的第二版中在一个切片缓冲内使用无线for循环直到文件尾部EOF读取文件并写入到标准输出。
```go
func cat(f *os.File) {
const NBUF = 512
var buf [NBUF]byte
for {
switch nr, err := f.Read(buf[:]); true {
case nr < 0:
fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error())
os.Exit(1)
case nr == 0: // EOF
return
case nr > 0:
if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
fmt.Fprintf(os.Stderr, "cat: error writing: %s\n", ew.Error())
}
}
}
}
```
代码来自于`cat2.go`使用了os包中的`os.file``Read`方法;`cat2.go``cat.go`具有同样的功能。
示例 12.14 [cat2.go](examples/chapter_12/cat2.go)
```go
package main
import (
"flag"
"fmt"
"os"
)
func cat(f *os.File) {
const NBUF = 512
var buf [NBUF]byte
for {
switch nr, err := f.Read(buf[:]); true {
case nr < 0:
fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error())
os.Exit(1)
case nr == 0: // EOF
return
case nr > 0:
if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
fmt.Fprintf(os.Stderr, "cat: error writing: %s\n", ew.Error())
}
}
}
}
func main() {
flag.Parse() // Scans the arg list and sets up flags
if flag.NArg() == 0 {
cat(os.Stdin)
}
for i := 0; i < flag.NArg(); i++ {
f, err := os.Open(flag.Arg(i))
if f == nil {
fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
os.Exit(1)
}
cat(f)
f.Close()
}
}
```
## 链接
- [目录](directory.md)
- 上一节:[用buffer读取文件](12.5.md)
- 下一节:[用defer关闭文件](12.7.md)