Weitere ähnliche Inhalte Ähnlich wie Golangintro (20) Golangintro4. 主要目标
Bruce Eckel 表示:
C++的复杂性(新C++更复杂),对于生产效率的影响,已经不
再合理了。程序员为了使用好C++, 需要跳过很多坑,是完全说不
通的,只是浪费你的时间和精力。现在,go对C++想要解决的那类
问题,做的更合理。
( Bruce Eckel: The complexity of C++ (even more complexity has been added
in the new C++), and the resulting impact on productivity, is no longer justified. All
the hoops that the C++ programmer had to jump through in order to use a C-
compatible language make no sense anymore -- they‗re just a waste of time and
effort. Now, Go makes much more sense for the class of problems that C++ was
originally intended to solve.)
10. 基本特征
1. 一门系统编程语言
2. 开源(社区性)
3. 语法接近C语言(因为Ken的一脉相承)
4. 多平台支持 (Linux,Mac,Windows,BSD)
5. 静态语言,需要编译
6. 自动内存管理,垃圾回收(GC)
官方主页: http://golang.org
官方教程: http://tour.golang.org/ (极其重要,一定要拿100分!)
11. 关键字
共25个关键词(ANSI C语言32 个,C++ 63个,Lua 20个,Java50个)
GO语言在关键词使用上是非常吝啬的。
Keep it simple, make it general, and make it intelligible.
--- Douglas McIlroy
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
12. 运算符
优先级 运算符
最高 * / % << >> &
&^
+-|^
== != < <= > >=
<-
&&
最低 ||
1. 省掉了~取反符,单目^表示取反,
2. 调整了 & 和 == 的优先级
(在C语言中 位运算的 & ^ | 竟比比较运算
< == 优先级还低这一点不科学,因为合乎情
理的写法是 a&1 == 0,但实际上必须写
(a&1) == 0。不过,这一问题的来源是历史
遗留,在 C89 之前,K&R C 并没有逻辑运算
符 && 和 ||,而是使用 & 和 | 来表示这一
意义,按使用的上下文区分意义。后来 C89
标准化,虽然增加了语义更合理的 && 和 ||,
但大概是为了兼容旧代码,也没有把这个优先
级改过来,结果就将错就错了。)
int main(void) {
int a = 2;
printf("%dn", a&1==0);
printf("%dn", (a&1)==0);
} (奇偶性)
13. int8 int16 int32 int64
uint8 uint16 uint32 uint64
float32 float64 string rune
complex64 complex128 ...
基础数据类型
基本数据类型完全符合C99标准<stdint.h>, 即确定长度的严格数
据类型, 如:
UTF-8字符
原生支持
(想想Rob Pike)
go源码亦为utf8
rune [ruːn]: n. 诗歌;古代北欧文字;神秘的记号
LONG, LONG LONG ? NO!
15. 与JSON的对比
JSON规范中,定义了:
object = { string:value } 无穷“名称/值”对
array = [value,value,value] 无穷 有序集合
value = string, number…array… 基本类型
并可形成一种无穷嵌套关系:
object:{ object:{ object:{object:,...}, ...},...}
在go语言中,go的数据结构和json是同构的。从go语言的数据结构导入导出
json格式,只需要一行代码。(想到robert了么,还想到了什么?)
map[string]interface{} --> 无穷键值对
slice interface{} --> 无穷有序集合
在GO构造一个
LOOP试试
21. 系统编程
Go语言重新封装了所有的系统调用,具有和C语言相同的对系统的操
作能力。(PS: thompson和pike都设计过OS)
25 TEXT runtime·open(SB),7,$0
26 MOVL $5, AX // syscall-5 - open
27 MOVL 4(SP), BX // pathname
28 MOVL 8(SP), CX // flag
29 MOVL 12(SP), DX // mode
30 CALL *runtime·_vdso(SB)
31 RET
int open(const char *pathname, int flags, mode_t mode);
引自:
http://golang.org/src/pkg/runtime/sys_linux_386.s
系统调用是内核所
能提供的全部功能
24. 名字空间和类 VS. 目录
1. 一个目录中的所有文件同属一个namespace (朴素思想来源?)
2. 同一目录、不同文件的变量,函数,互相可见,因此也类似于
Class
3. 小写字母开头的为private函数/变量
func test() var a 对其他目录不可见
4. 大写字母开头的为public函数/变量
func Test() var A 对其他目录可见
25. 对象方法 VS. 接收函数
func (slice ByteSlice) Append(data []byte) []byte {
}
Go语言没有类的概念,比较接近的是结构体。
可以定义一个结构体,并给这个结构体定义一个接收函数,然后通过
―对象 点 方法‖的形式去调用一个struct 方法(函数指针?)例如
aSlice.Append(…)
但没有完整意义上的对象方法, 也没有隐含的this指针.
26. 继承 VS. 嵌入
type A struct {
a int
}
type B struct {
b int
}
嵌入:
type AB struct {
A
B
}
可以将两个struct内的字段合并到一
个新的结构体。
30. DEFER OR FINALLY
defer 的作用类似于finally:
C++代码
try {
fd = fopen(―xxx‖)
}
catch(…) {}
finally() {
close(fd)
}
等价于:
f, err := os.Open(―xxx‖)
If err!= nil …..
defer f.close()
43. GOROUTINE + EPOLL
listener, err := net.ListenTCP("tcp", tcpAddr)
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handleClient(conn)
}
That's all for a C10K server....
网络接口部分,golang在Linux的IO模型是基于epoll的,并对上层完全透明
因此,网络部分非常简单,并且高效。 (BSD是kqueue实现)
45. GOROUTINE调度点
1. channel send/recv/select/close (收、发、选、关)
2. malloc (内部内存分配)
3. garbage collection
4. goroutine sleep
5. syscalls (所有系统调用)
基本上,golang的设计在所有可能阻塞的调用中,都尝试主动让出
CPU,让其他任务继续执行。 例如,系统调用 open(),其调度的
有效性,基本等同于操作系统级别(进程遇到阻塞操作会被put to
sleep)。
48. CLASSICAL IPC
PATTERNS
• mutex(互斥) -- pthread_mutex_init()
• rwlock(读写锁) -- pthread_rwlock_init()
• shm (共享内存) -- shm_open()
• semaphore(信号量) -- sem_open()
• pipe(管道) -- pipe()
• socket -- socket
• condwait(条件等待) –- pthread_cond_wait()
• signal(信号) -- kill()
传统的UNIX系统中,以上所有机制在都是由内核提供的功能。
Go语言也提供以上的IPC机制。
49. IPC相关技术出现的
年代整理
process 60年代早期(冷战早期)
semaphore 1965年由 dijkstra 提出(PV)
signal 1970年在贝尔实验室的Unix系统出现。
pipe 1973年,ken thompson在unix中实现,最初由数学
家 Douglas McIlroy提出
message queue 1980年出现在VRTX和pSOS+(vxworks前生)。
sockets 1983年首次出现于4.2BSD系统,直到1989年才免于
版权保护。
poll 1986年在SVR3 Unix出现。
threads 直到90年代晚期都没有太多的支持,本世纪才普及。
kqueue 2000年在freebsd 4.1中出现。
epoll 2002年在linux 2.5.44中出现。
50. 通信顺序进程(CSP)
CSP := Communication Sequential Processing
is a formal language for describing patterns of interaction in concurrent systems.
一种用于定义并行交互的形式语言.
eg: COPY = *[c:character; west?c → east!c]
CSP was first described in a 1978 paper by C. A. R. Hoare(東尼·霍爾)
• 1980年,获颁图灵奖。
• 1982年,成为英国皇家学会院士。
• 2000年,因为他在计算机科学与教育方面的杰出贡献,获得英国王室颁赠爵士头衔。
(思考:霍爾还做过什么算法?)
53. CSP举例
package main
func main() {
ch := make(chan int,10)
ch <- 1
v := <-ch
println(v)
}
不符合CSP语义, 异步消息
package main
func main() {
ch := make(chan int)
ch <- 1
v := <-ch
println(v)
}
运行出错,但符合CSP语义,
因为收发不可能同时成功
(思考,会报什么错)
55. 一个基本的消息循环
for {
select {
case msg, ok := <-in: // 来自网络
case msg, ok := <-sess.MQ: // 来自其他goroutine
case _ = <-std_timer: // 定时器
}
}
检查每个case语句:
1. 如果有仸意一个chan是send or recv read,那么就执行该block
2. 如果多个case是ready的,那么随机找1个并执行该block
3. 如果都没有ready,那么就block and wait
4. 如果有default,而且其他的case都没有ready,就执行该default
注意: select channel 没有优先级之分,但能通过调整代码模拟。(思考用什么?)
58. CGO & C
CGO是GO同C语言交互的方法:
package rand
/*
#include <stdlib.h>
*/
import "C"
func Random() int {
return int(C.rand())
}
func Seed(i int) {
C.srand(C.uint(i))
}
有时候我们需要调用一些
C写的程序, 例如嵌入
LUA,以获得脚本的能力。
Go和C的血缘关系,使得
嵌入C非常容易。
目前在github上已经出现
了以golua, luar为代表的
package,使用非常方便。
60. 一个CGO的应用
$ telnet localhost 8800
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GameServer LUA Console
> a=1
> b=2
> print(a+b)
3
> users = gsdb.ListAll()
> print(users)
[]int32
有时候我们需要像ruby console
那样的灵活性,可以在线的时候
观察,或者改变某些数值。
我们通过CGO嵌入LUA,可以
实现一个类似的Console,在调
试的时候尤其重要。