Goqr
on
github
测试环境:
(包含写文件io时间)
Macbook
pro
8ms
/
qr
,
go
1.0.3
Linux
29
/
30
,
3-‐4
ms/
qr
,
go
1.1
并发
/
批量输出
/
可支持web服务
QFG
on
gitlab 二维自造,加强版,
定制qr颜色图片等,
直接输出
base64
Slide 9
Slide 9 text
干脆面..
Php
>
1min
Ruby
~
14s
Go
~
4s
….
1000次循环
Slide 10
Slide 10 text
Mortar
on
gitlab
Key
/
value
存储
队列
数组
计数器
性能:
10w写入
19s
,
redis
21s
100w写入207s,
redis
212s
Variable
Declarafons(变量声明)
var
sum
int
//
Just
a
declarafon
var
total
int
=
42
//
A
declarafon
with
inifalizafon
第一眼看上去有些奇怪,但这样是有好处的,例如下面的这个C
代码片段:
int*
a,
b;
这就意味着a是一个指针,但b却不是。要声明他们都是指针必
须重复两次,但在Go中,你可以这样声明:
var
a,
b
*int
当一个变量被初始化后,编译器会自动识别他的类型,所以不
必要指明其类型:
var
label
=
"name"
这样var关键字也就多余了,因此作者提出了一个新的赋值操作
符声明并初始化一个新变量:
name
:=
"Samuel"
Slide 32
Slide 32 text
Condifonals(条件)
Go中的条件句使用If-‐else,与C语言相同。但是它的条件不需
要包含在括号中,这将减少阅读代码时的视觉混乱。当然,
在条件之前还可以添加一个简单的声明。
result
:=
someFunc();
if
result
>
0
{
/*
Do
something
*/
}
else
{
/*
Handle
error
*/
}
还可以:
if
result
:=
someFunc();
result
>
0
{
/*
Do
something
*/
}
else
{
/*
Handle
error
*/
}
Slide 33
Slide 33 text
Switches
Switches
语句也与C类似,但是在C的基础上
进行了改进。
C
代码:
int
result;
switch
(byte)
{
case
'a':
case
'b':
{
result
=
1
break
}
default:
result
=
0
}
Go
代码:
var
result
int
switch
byte
{
case
'a',
'b':
result
=
1
default:
result
=
0
}
Slide 34
Slide 34 text
Go
匹配的不仅仅是integer和character类型。
C
代码:
int
result
=
calculate();
if
(result
<
0)
{
/*
negafve
*/
}
else
if
(result
>
0)
{
/*
posifve
*/
}
else
{
/*
zero
*/
}
Go
代码:
switch
result
:=
calculate();
true
{
case
result
<
0:
/*
negafve
*/
case
result
>
0:
/*
posifve
*/
default:
/*
zero
*/
}
当switch的值被忽略时,假设为真,所以上述代码还可
简化为:
switch
result
:=
calculate();
{
case
result
<
0:
/*
negafve
*/
case
result
>
0:
/*
posifve
*/
default:
/*
zero
*/
}
Ø 变量
ü 变量声明
var
v1
int
var
v2
string
var
v3
[10]
int
var
(
v1
int
v2
string
)
ü 变量初始化
var
v1
int
=
10
//ok
var
v2
=
10
//ok
v3
:=
10
//ok
v2
:=
10
//error
Ø 流程控制
ü 条件语句
if
a
<
5
{
return
0
}
else
{
return
1
}
ü 选择语句
switch
i
{
case
0
:
fmt.Printf
(“0”)
case
1
:
fallthrough
case
2,
3
:
fmt.Printf
(“2,3”)
default:
fmt.Printf
(“default”)
}
Slide 41
Slide 41 text
Ø 流程控制
ü 选择语句
switch
{
case
0
<=
Num
&&
Num
<=
3
:
fmt.Printf
(“0-‐3”)
case
4
<=
Num
&&
Num
<=
6
:
fmt.Printf
(“4-‐6”)
}
ü 循环语句
//case
1
sum
:=
0
for
i
:=
0;
i
<
10;
i++
{//条件表达式中也支持多重赋值
sum
+=
i
}
//case2
sum
:=
0
for
{
//相当于while,do-‐while
sum++
//支持按标签break
}
Ø 并发通信
ü 缓冲机制
timeout
:=
make
(chan
bool,
1)
go
func
()
{
time.Sleep
(1e9)
//等待1秒
timeout
<-‐
true
}
()
select
{
case
<-‐
ch
:
case
<-‐
timeout
:
default
:
}
创建一个带缓冲的channel:c
:=
make
(chan
int,
1024)
ü 超时机制
Go语言没有提供直接的超时处理机制,但我们可以利用select
机制实现一套
Slide 53
Slide 53 text
Ø 并发通信
ü channel的传递
type
PipeData
struct
{
value
int
handler
func
(int)
int
next
chan
int
}
func
handler
(queue
chan
*PipeData)
{
for
data
:=
range
queue
{
data.next
<-‐
data.handler
(data.value)
}
}
Go语言中channel本身是一个原生类型,因此channel可以传递。
下面我们利用这个特性来实现*nix常见的管道特性
Slide 54
Slide 54 text
Ø 并发通信
ü 单向channel
var
ch1
chan
int
//ch1是一个正常的channel,不是单向的
var
ch2
chan<-‐
float64
//ch2是单向的,只用于写float64数据
var
ch3
<-‐chan
int
//ch3是单向的,只用于读取int数据
//单向channel与双向channel之间的转换
ch4
:=
make
(chan
int)
ch5
:=
<-‐chan
int
(ch4)
//ch5为单向的读取channel
ch6
:=
chan<-‐
int
(ch4)
//ch6为单向的写入channel
我们在将一个channel变量传递到一个函数时,可以通过将其制定为单向
channel变量,从而限制该函数中可以对此channel的操作。