修正半角标点符号

This commit is contained in:
kimw
2018-06-09 16:27:25 +00:00
parent a81bfabcdc
commit 7ebd75aeae
60 changed files with 132 additions and 132 deletions

View File

@@ -4,7 +4,7 @@
`os`包以跨平台的方式提供了一些与操作系统交互的函数和变量。程序的命令行参数可从os包的Args变量获取os包外部使用os.Args访问该变量。
os.Args变量是一个字符串string的*切片*slice译注slice和Python语言中的切片类似是一个简版的动态数组切片是Go语言的基础概念稍后详细介绍。现在先把切片s当作数组元素序列序列的长度动态变化`s[i]`访问单个元素,用`s[m:n]`获取子序列(译注和python里的语法差不多)。序列的元素数目为len(s)。和大多数编程语言类似区间索引时Go言里也采用左闭右开形式区间包括第一个索引元素不包括最后一个因为这样可以简化逻辑。译注比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3]不包含最后一个元素。比如s[m:n]这个切片0 ≤ m ≤ n ≤ len(s)包含n-m个元素。
os.Args变量是一个字符串string的*切片*slice译注slice和Python语言中的切片类似是一个简版的动态数组切片是Go语言的基础概念稍后详细介绍。现在先把切片s当作数组元素序列序列的长度动态变化`s[i]`访问单个元素,用`s[m:n]`获取子序列译注和python里的语法差不多。序列的元素数目为len(s)。和大多数编程语言类似区间索引时Go言里也采用左闭右开形式区间包括第一个索引元素不包括最后一个因为这样可以简化逻辑。译注比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3]不包含最后一个元素。比如s[m:n]这个切片0 ≤ m ≤ n ≤ len(s)包含n-m个元素。
os.Args的第一个元素os.Args[0]是命令本身的名字其它的元素则是程序启动时传给它的参数。s[m:n]形式的切片表达式产生从第m个元素到第n-1个元素的切片下个例子用到的元素包含在os.Args[1:len(os.Args)]切片中。如果省略切片表达式的m或n会默认传入0或len(s)因此前面的切片可以简写成os.Args[1:]。

View File

@@ -46,7 +46,7 @@ counts[line] = counts[line] + 1
`map`中不含某个键时不用担心,首次读到新行时,等号右边的表达式`counts[line]`的值将被计算为其类型的零值,对于`int`即0。
为了打印结果,我们使用了基于`range`的循环,并在`counts`这个`map`上迭代。跟之前类似,每次迭代得到两个结果,键和其在`map`中对应的值。`map`的迭代顺序并不确定,从实践来看,该顺序随机,每次运行都会变化。这种设计是有意为之的,因为能防止程序依赖特定遍历顺序,而这是无法保证的。(译注具体可以参见这里http://stackoverflow.com/questions/11853396/google-go-lang-assignment-order)
为了打印结果,我们使用了基于`range`的循环,并在`counts`这个`map`上迭代。跟之前类似,每次迭代得到两个结果,键和其在`map`中对应的值。`map`的迭代顺序并不确定,从实践来看,该顺序随机,每次运行都会变化。这种设计是有意为之的,因为能防止程序依赖特定遍历顺序,而这是无法保证的。译注具体可以参见这里http://stackoverflow.com/questions/11853396/google-go-lang-assignment-order
继续来看`bufio`包,它使处理输入和输出方便又高效。`Scanner`类型是该包最有用的特性之一,它读取输入并将其拆成行或单词;通常是处理行形式的输入最简单的方法。

View File

@@ -1,6 +1,6 @@
## 1.4. GIF动画
下面的程序会演示Go语言标准库里的image这个package的用法我们会用这个包来生成一系列的bit-mapped图然后将这些图片编码为一个GIF动画。我们生成的图形名字叫利萨如图形(Lissajous figures)这种效果是在1960年代的老电影里出现的一种视觉特效。它们是协振子在两个纬度上振动所产生的曲线比如两个sin正弦波分别在x轴和y轴输入会产生的曲线。图1.1是这样的一个例子:
下面的程序会演示Go语言标准库里的image这个package的用法我们会用这个包来生成一系列的bit-mapped图然后将这些图片编码为一个GIF动画。我们生成的图形名字叫利萨如图形Lissajous figures这种效果是在1960年代的老电影里出现的一种视觉特效。它们是协振子在两个纬度上振动所产生的曲线比如两个sin正弦波分别在x轴和y轴输入会产生的曲线。图1.1是这样的一个例子:
![](../images/ch1-01.png)
@@ -76,7 +76,7 @@ func lissajous(out io.Writer) {
[]color.Color{...}和gif.GIF{...}这两个表达式就是我们说的复合声明4.2和4.4.1节有说明。这是实例化Go语言里的复合类型的一种写法。这里的前者生成的是一个slice切片后者生成的是一个struct结构体。
gif.GIF是一个struct类型参考4.4节。struct是一组值或者叫字段的集合不同的类型集合在一个struct可以让我们以一个统一的单元进行处理。anim是一个gif.GIF类型的struct变量。这种写法会生成一个struct变量并且其内部变量LoopCount字段会被设置为nframes而其它的字段会被设置为各自类型默认的零值。struct内部的变量可以以一个点(.)来进行访问就像在最后两个赋值语句中显式地更新了anim这个struct的Delay和Image字段。
gif.GIF是一个struct类型参考4.4节。struct是一组值或者叫字段的集合不同的类型集合在一个struct可以让我们以一个统一的单元进行处理。anim是一个gif.GIF类型的struct变量。这种写法会生成一个struct变量并且其内部变量LoopCount字段会被设置为nframes而其它的字段会被设置为各自类型默认的零值。struct内部的变量可以以一个点.来进行访问就像在最后两个赋值语句中显式地更新了anim这个struct的Delay和Image字段。
lissajous函数内部有两层嵌套的for循环。外层循环会循环64次每一次都会生成一个单独的动画帧。它生成了一个包含两种颜色的201*201大小的图片白色和黑色。所有像素点都会被默认设置为其零值也就是调色板palette里的第0个值这里我们设置的是白色。每次外层循环都会生成一张新图片并将一些像素设置为黑色。其结果会append到之前结果之后。这里我们用到了append(参考4.2.1)内置函数将结果append到anim中的帧列表末尾并设置一个默认的80ms的延迟值。循环结束后所有的延迟值被编码进了GIF图片中并将结果写入到输出流。out这个变量是io.Writer类型这个类型支持把输出结果写到很多目标很快我们就可以看到例子。

View File

@@ -63,7 +63,7 @@ goroutine是一种函数的并发执行方式而channel是用来在goroutine
main函数中用make函数创建了一个传递string类型参数的channel对每一个命令行参数我们都用go这个关键字来创建一个goroutine并且让函数在这个goroutine异步执行http.Get方法。这个程序里的io.Copy会把响应的Body内容拷贝到ioutil.Discard输出流中译注可以把这个变量看作一个垃圾桶可以向里面写一些不需要的数据因为我们需要这个方法返回的字节数但是又不想要其内容。每当请求返回内容时fetch函数都会往ch这个channel里写入一个字符串由main函数里的第二个for循环来处理并打印channel里的这个字符串。
当一个goroutine尝试在一个channel上做send或者receive操作时这个goroutine会阻塞在调用处直到另一个goroutine从这个channel里接收或者写入值这样两个goroutine才会继续执行channel操作之后的逻辑。在这个例子中每一个fetch函数在执行时都会往channel里发送一个值(ch <- expression)主函数负责接收这些值(<-ch)这个程序中我们用main函数来接收所有fetch函数传回的字符串可以避免在goroutine异步执行还没有完成时main函数提前退出
当一个goroutine尝试在一个channel上做send或者receive操作时这个goroutine会阻塞在调用处直到另一个goroutine从这个channel里接收或者写入值这样两个goroutine才会继续执行channel操作之后的逻辑。在这个例子中每一个fetch函数在执行时都会往channel里发送一个值ch <- expression主函数负责接收这些值<-ch这个程序中我们用main函数来接收所有fetch函数传回的字符串可以避免在goroutine异步执行还没有完成时main函数提前退出
**练习 1.10** 找一个数据量比较大的网站用本小节中的程序调研网站的缓存策略对每个URL执行两遍请求查看两次时间是否有较大的差别并且每次获取到的响应内容是否一致修改本节中的程序将响应结果输出以便于进行对比

View File

@@ -34,9 +34,9 @@ func Signum(x int) int {
这种形式叫做无tag switch(tagless switch)这和switch true是等价的。
像for和if控制语句一样switch也可以紧跟一个简短的变量声明一个自增表达式、赋值语句或者一个函数调用(译注:比其它语言丰富)
像for和if控制语句一样switch也可以紧跟一个简短的变量声明一个自增表达式、赋值语句或者一个函数调用译注:比其它语言丰富
break和continue语句会改变控制流。和其它语言中的break和continue一样break会中断当前的循环并开始执行循环之后的内容而continue会跳过当前循环并开始执行下一次循环。这两个语句除了可以控制for循环还可以用来控制switch和select语句(之后会讲到)在1.3节中我们看到continue会跳过内层的循环如果我们想跳过的是更外层的循环的话我们可以在相应的位置加上label这样break和continue就可以根据我们的想法来continue和break任意循环。这看起来甚至有点像goto语句的作用了。当然一般程序员也不会用到这种操作。这两种行为更多地被用到机器生成的代码中。
break和continue语句会改变控制流。和其它语言中的break和continue一样break会中断当前的循环并开始执行循环之后的内容而continue会跳过当前循环并开始执行下一次循环。这两个语句除了可以控制for循环还可以用来控制switch和select语句之后会讲到在1.3节中我们看到continue会跳过内层的循环如果我们想跳过的是更外层的循环的话我们可以在相应的位置加上label这样break和continue就可以根据我们的想法来continue和break任意循环。这看起来甚至有点像goto语句的作用了。当然一般程序员也不会用到这种操作。这两种行为更多地被用到机器生成的代码中。
**命名类型:** 类型声明使得我们可以很方便地给一个特殊类型一个名字。因为struct类型声明通常非常地长所以我们总要给这种struct取一个名字。本章中就有这样一个例子二维点类型