翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Non-Blocking Channel Operations

普通管道的发送与接收都是阻塞的,然而我们可以使用select的default条件来实现非阻塞的发送,接收和甚至是非阻塞的多路复用的selects

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import "fmt"

func main() {
messages := make(chan string)
signals := make(chan bool)

// 这里是一个非阻塞的接收者,如果管道msg就绪的话select会使用管道值执行这条分支
// 否则的话select会执行default分支
select {
case msg := <-messages:
fmt.Println("recieved message", msg)
default:
fmt.Println("no message received")
}

// 类似的非阻塞的发送者
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}

// 可以在default分支前使用多个条件分支用于实现一个非阻塞的多路复用select
// 下面的例子尝试同时非阻塞的接收messages和signals两个管道的值
select {
case msg := <-messages:
fmt.Println("recieved messages", msg)
case sig := <-signals:
fmt.Println("recieved signals", sig)
default:
fmt.Println("no activity")
}
}
1
2
3
4
tashuo:golang ta_shuo$ go run non-blocking-channel.go
no message received
no message sent
no activity

原文链接:Go by Example: Non-Blocking Channel Operations

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Timeouts

超时对于需要联接外部资源或需要限定执行时间的程序非常重要,在golang中因为存在channelselect使得超时实现起来非常简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import "time"
import "fmt"

func main() {
// 通过管道c1模拟一个2s后才有返回值的外部请求
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()

// 使用select执行一条超时操作
// res等待管道c1的值,<-time.After(time.Second * 1)等待一个一秒后发送的值。
// 由于select会执行第一个就绪的条件,所以如果前者执行时间超过后者代码中规定的一秒便会进入后者超时的情况
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout1")
}

// 由于res会在两秒后就绪,小于超时的三秒限制,所以不会超时
c2 := make(chan string)
go func() {
time.Sleep(time.Second * 2)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(time.Second * 3):
fmt.Println("timeout 2")
}
}
1
2
3
tashuo:golang ta_shuo$ go run timeout.go
timeout1
result 2

使用select结构的超时模式需要借助管道进行通信,这通常是个好主意因为其他一些golang重要的功能也是基于管道和select。

原文链接:Go by Example: Timeouts

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Select

select允许程序等待多个管道操作,使用select来组合goroutinechannel是golang的一项重要的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "time"
import "fmt"

func main() {
// 定义两个管道用来测试`select`
c1 := make(chan string)
c2 := make(chan string)

// 每个管道变量在独立的goroutine中隔若干时间后接收到一个值,用来模拟阻塞的RPC调用
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()

// 使用`select`同时等待这些管道变量,并且当管道有值时就将其打印出来
for i := 0; i < 2; i++ {
select {
case msg1 <- c1:
fmt.Println("received", msg1)

case msg2 <- c2:
fmt.Println("received", msg2)
}
}
}

1
2
3
4
5
6
$ time go run select.go 
received one
received two

// 由于两个睡眠操作是并行执行的,所以执行时间并没有超过3秒
real 0m2.245s

原文链接:Go by Example: Select

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Channel Directions

当使用管道作为函数参数时,可以显式声明该管道是作为发送者还是接收者,这种特性增加了程序的类型安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import "fmt"

// 定义ping函数只接受用来发送值的管道参数(即管道是接收者)
// 如果试图从该管道参数中接收值,编译将会报错
func ping(pings chan<- string, msg string) {
pings <- msg
}

// pong函数接受一个用来接收值的管道pings(即管道是发送者)和一个用来发送值的管道pongs(即管道是接收者)
func pong(pings <-chan string, pongs chan<- string) {
msg := <-pings
pongs <- msg
}

func main() {
pings := make(chan string, 1)
pongs := make(chan string, 1)

// 将消息发送到管道pings
ping(pings, "passed message")

// 将管道pings中的值发送至管道pongs中
pong(pings, pongs)
fmt.Println(<-pongs)
}
1
2
$ go run channel-directions.go
passed message

原文链接:Go by Example: Channel Directions

作者:[法] 罗曼·罗兰

出版年: 2012-1-1

出版社: 江苏文艺

译者:傅雷

ISBN: 9787539946801

豆瓣链接:https://book.douban.com/subject/7000672/



卷三 · 少年

第三部 · 阿达 <部分段落节选 P275-P282>


克里斯朵夫认为责任是例外的固然不错,但爱情也一样是例外的。一切都是例外的。一切有点儿价值的东西,它的最可怕的敌人,并非是不好的东西,–(连恶意也有它的价值,)–而是它本身成了习惯性。心灵的致命的仇敌,乃是时间的磨蚀。

阿达开始厌倦了。她不够聪明,不知道在一个像克里斯朵夫那样生机勃勃的人身上,想法使她的爱情与日俱新。在这次爱情中间,她的感官和虚荣心已经把所有的乐趣都榨取到了。现在她只剩下一桩乐趣,就是把爱情毁灭。她有那种暧昧的本能,为多少女子(连善良的在内)多少男子(连聪明的在内)所共有的。–他们都不能在人生中有所创造:作品,儿女,行动,什么都不能,但还有相当的生命力,受不了自己的一无所用。他们但愿别人跟自己一样的没用,便竭力想做到这一点。有时候这是无心的;他们一发觉这种居心不良的欲望,就大义凌然的把它打消。但多数的时候他们鼓励这种欲望,尽量把一切活着的,喜欢活着的,有资格活着的,加以摧毁;而摧毁的程度当然要看他们的力量如何:有些事小规模的,仅仅以周围亲近的人为对象;有些是大举进攻,以广大的群众为目标。把伟大的人物伟大的思想拉下来,拉得跟自己一般高低的批评家,还有以引诱爱人堕落为快的女孩子,是两种性质相同的恶兽。–可是后面的一种更讨人喜欢。

因此阿达极想把克里斯朵夫腐化一下,使他屈辱。其实她还没有这个力量。便是腐化人家,她那点聪明也嫌不够;她自己也觉得,所以她怀恨克里斯朵夫的一大原因,就是她的爱情没有力量伤害他。她不承认有伤害他的欲望;要是能阻止自己,也许她还不会这么做。但她认为要伤害他而办不到未免太岂有此理。倘使一个女人没有一种幻像,使她觉得能完全驾驭那个爱她的人,给他不论是好是坏的影响,那就是这个男人爱她爱得不够,而她非要试试自己的力量不可了。克里斯朵夫没有留意到这些,所以阿达说着玩儿问他:

阅读全文 »

文档原地址:EXPLAIN Output Format

EXPLAIN提供一些MySQL执行SQL语句的信息,包括SELECT, DELETE, INSERT, REPLACE和UPDATE等语句。

MySQL 5.6.3之前只支持SELECT

简介

EXPLAIN作用于SELECT语句时会返回一列信息。SELECT语句会按照一定顺序输出表的内容。MySQL使用循环嵌套的方式处理所有的连表操作。这意味着MySQL会从第一张表中读取一行数据,然后在第二张表中读出相匹配的数据,然后第三张表等等。当所有的表都被执行到,MySQL会输出选中的列并且回溯表的数据直到找到匹配更多行的表。从找到的这个表里面读取下一行数据,然后下一个表。

EXPLAIN的输出包含不同的分割开来的数据。另外,对于SELECT语句,EXPLAIN还会生成一些额外的信息与SHOW WARNING的输出一起显示。

输出内容

下面介绍EXPLAIN命令的输出内容,稍后会补充type,Extra两个字段的信息。

EXPLAIN输出的每行信息都对应于相应的一张表。每行输出的内容都总结在下文的表格中,表格最后一列是更加详细的说明。表格第一列是字段名,第二列是当加了FORMAT=JSON参数时跟第一列相同概念的字段名。

阅读全文 »

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Channel Synchronization

我们可以使用channel来同步不同goroutine的执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"
import "time"

// 定义一个函数,接收一个channel作为参数,该参数用来通知另一个goroutine该函数已经执行完毕
func worker(done chan bool) {
fmt.Println("working...")
time.Sleep(time.Second)
fmt.Println("done")

// 将成功信号发往channel
done <- true
}

func main() {
done := make(chan bool)

// 启动新的goroutine执行worker函数,并出入channel
go worker(done)

// 接收channel中的值
// 如果移除这一句可能收不到任何输出,因为程序可能在worker函数还未执行已经结束了
<-done
}
1
2
3
$ go run channel-synchronization.go      
working...
done

原文链接:Go by Example: Channel Synchronization

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Channel Buffering

默认情况下channel是没有缓冲区的,这意味着它们只会在有一个相应的接收者准备好接收管道数据时才会接受发送者往管道发送数据。有缓冲区的channel可以在没有相应接收者时接受发送者发送特定数量的数值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
// 创建一个string类型的,缓冲区长度为2的channel
messages := make(chan string, 2)

// 由于创建的channel有缓冲区,所以可以直接往里面发送数据而不需要有接收者。
messages <- "buffered"
messages <- "channel"

// 接收channel中的数据
fmt.Println(<-messages)
fmt.Println(<-messages)
}

原文链接:Go by Example: Channel Buffering

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Channels

channel是golang中连接不同goroutine之间的管道。你可以从一个goroutine往channel中发送数据而从另一个goroutine中获取到这些数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

func main() {
// 创建一个channel
messages := make(chan string)

// 使用'<-'操作符来往管道发送数据
// 在一个新的goroutine执行
go func() {
messages <- "ping"
}

// 使用'<-'操作符接收管道中的数据
// 这里会接收到从上面那个新开的goroutine中发往管道的"ping"
// 默认情况下对于管道的操作-发送和接收都是阻塞的,直到发送方和接收方准备就绪。
// 这个特性使得我们在程序结尾可以不用做任何同步操作而去等待接收管道中的数据"ping"。
msg := <- messages
fmt.Println(msg)
}
1
2
$ go run channels.go 
ping

原文链接:Go by Example: Channels

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Goroutines

golang中的goroutine是一个比线程还要轻量的调度单位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func f(form string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}

func main() {
// 常用的函数调用方式,同步执行
f("direct")

// 使用go关键字来启动goroutine执行函数,跟正在执行的函数调用并行执行
go f("goroutine")

// 也可以启动goroutine执行匿名函数
go func(msg string) {
fmt.Println(msg)
}("going")

// 上面两个go启动的函数调用在独立的goroutine中异步执行
// 下面Scanln函数在接收到外界一个输入时结束程序
var input string
fmt.Scanln(&input)
fmt.Println("done")
}
1
2
3
4
5
6
7
8
9
10
11
// 从输出的结果,匿名函数的输出插入在第一个goroutine的输出中,可看出两个函数调用是在独立的goroutine中并行执行
$ go run goroutines.go
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
<enter>
done

原文链接:Go by Example: Goroutines