go 一
go学习 一
go语言的优势
go学习 一
go语言的优势
1、Go有什么优势
- 可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
- 静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
- 语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
- 内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
- 简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
- 丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
- 内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
- 跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
- 内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。
2、Go适合用来做什么
- 服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
- 分布式系统,数据库代理器等
- 网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用、
- 内存数据库,前一段时间google开发的groupcache,couchbase的部分组建
- 云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。
3、Go成功的项目
nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息
docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
skynet:分布式调度框架
Doozer:分布式同步工具,类似ZooKeeper
Heka:mazila开源的日志处理系统
cbfs:couchbase开源的分布式文件系统
tsuru:开源的PAAS平台,和SAE实现的功能一模一样
groupcache:memcahe作者写的用于Google下载系统的缓存系统
god:类似redis的缓存系统,但是支持分布式和扩展性
gor:网络流量抓包和重放工具
以下是一些公司,只是一小部分:
- http://Apcera.com
- http://Stathat.com
- Juju at Canonical/Ubuntu, presentation
- http://Beachfront.iO at Beachfront Media
- CloudFlare
- Soundcloud
- Mozilla
- Disqus
- http://Bit.ly
- Heroku
- youtube
学习地址 :点我
go学习 一
go语言的优势
1、Go有什么优势
- 可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
- 静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
- 语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
- 内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
- 简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
- 丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
- 内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
- 跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
- 内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。
2、Go适合用来做什么
- 服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
- 分布式系统,数据库代理器等
- 网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用、
- 内存数据库,前一段时间google开发的groupcache,couchbase的部分组建
- 云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。
3、Go成功的项目
nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息
docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
skynet:分布式调度框架
Doozer:分布式同步工具,类似ZooKeeper
Heka:mazila开源的日志处理系统
cbfs:couchbase开源的分布式文件系统
tsuru:开源的PAAS平台,和SAE实现的功能一模一样
groupcache:memcahe作者写的用于Google下载系统的缓存系统
god:类似redis的缓存系统,但是支持分布式和扩展性
gor:网络流量抓包和重放工具
以下是一些公司,只是一小部分:
- http://Apcera.com
- http://Stathat.com
- Juju at Canonical/Ubuntu, presentation
- http://Beachfront.iO at Beachfront Media
- CloudFlare
- Soundcloud
- Mozilla
- Disqus
- http://Bit.ly
- Heroku
- youtube
学习地址 :点我
go run go build的区别
程序基本语法
- 所有go源码以.go结尾;
- 注释不会被编译,单行注释是以 // 开头,多行注释以 /* 开头,以 */ 结尾;
- 标识符以字母或下划线开头,大小写敏感,_ 是特殊标识符,用来忽略结果;
- 保留关键字:
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 |
append | bool | byte | cap | close | complex | complex64 | complex128 | uint16 |
copy | false | float32 | float64 | imag | int | int8 | int16 | uint32 |
int32 | int64 | iota | len | make | new | nil | panic | uint64 |
println | real | recover | string | true | uint | uint8 | uintptr |
程序基本结构
1. 任何一个代码文件隶属于一个包
2. golang可执行程序,package main,并且有且只有一个main入口函数
3. 包中函数调用:
- 同一个包中函数,直接调用
- 不同包中函数,通过包名+点+函数名进行调用
4. 包访问控制规则:
- 大写意味着这个函数/变量是可导出的
- 小写意味着这个函数/变量是私有的,包外部不能访问
项目目录
$ tree project project ├── bin │ ├── example1 │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── day1 │ ├── example1 │ │ ├── debug │ │ └── hello.go │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender Src 源码文件 Bin 编译后二进制文件 vender 第三方 pkg 静态文件
简单栗子
$ tree project project ├── bin │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── test1 │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender
[main.go] package main import ( "fmt" "go_dev/test1/goroute_example/goroute" ) func main() { pipe := make(chan int, 1) go goroute.Add(pipe, 10, 20) sum := <-pipe fmt.Println(sum) }
[add.go] package goroute func Add(pipe chan int, a int, b int) { pipe <- (a + b) }
$ go build -o bin/goroute_example go_dev/test1/goroute_example/main $ bin/goroute_example 30 $
变量的声明和赋值
打印类型
fmt.Printf("sadf %T", c)
其他的打印方法不能使用 %T来打印类型
println和printf的区别
go println与printf区别 Println 与Printf 都是fmt 包中的公共方法 Println :可以打印出字符串,和变量; Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形, a := 10 fmt.Println(a) //right fmt.Println("abc") //right fmt.Printf("%d",a) //right fmt.Printf(a) //error %v 它可以以适当的格式输出任意的类型
常量的定义
const b = 10
不同类型的变量声明
枚举 iota
在常量中用
从0 开始 逐渐递增
字符和对应的ascci值的打印
字符和字符串的区别
格式输出
类型
【简介】 fmt 包实现了格式化 I/O 函数,类似于 C 的 printf 和 scanf。格式“占位符”衍生自 C,但比 C 更简单。 【打印】 占位符: [一般] %v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名 %#v 相应值的 Go 语法表示 %T 相应值的类型的 Go 语法表示 %% 字面上的百分号,并非值的占位符 [布尔] %t 单词 true 或 false。 [整数] %b 二进制表示 %c 相应 Unicode 码点所表示的字符 %d 十进制表示 %o 八进制表示 %q 单引号围绕的字符字面值,由 Go 语法安全地转义 %x 十六进制表示,字母形式为小写 a-f %X 十六进制表示,字母形式为大写 A-F %U Unicode 格式:U+1234,等同于 "U+%04X" [浮点数及其复合构成] %b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 的 'b' 转换格式一致。例如 -123456p-78 %e 科学计数法,例如 -1234.456e+78 %E 科学计数法,例如 -1234.456E+78 %f 有小数点而无指数,例如 123.456 %g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的 0)输出 %G 根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的 0)输出 [字符串与字节切片] %s 字符串或切片的无解译字节 %q 双引号围绕的字符串,由 Go 语法安全地转义 %x 十六进制,小写字母,每字节两个字符 %X 十六进制,大写字母,每字节两个字符 [指针] %p 十六进制表示,前缀 0x [注意]
格式化输入
scan 或者scanf
scan 不需要写入格式 自动匹配格式
类型转换
类型别名
给类型取别名,打印相应数据的类型会打印出类型的别名,也可以直接定义此别名类型的变量
运算符
Go语言运算符 Go语言运算符优先级,是描述在计算机运算计算表达式时执行运算的先后顺序。 先执行具有较高优先级的运算,然后执行较低优先级的运算。 例如,我们常说的先执行相乘和除,再执行加减运算。 Go 语言内置的运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 下面我们来对应Go语言各个运算符,算术、关系、逻辑、按位、赋值和其他运算符的详细讲解。 一、Go语言 算术运算符 下表显示了Go语言支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 + 添加两个操作数 A+B=30 - 从第一个操作数中减去第二个操作数 A-B=10 * 将两个操作数相乘 A*B=200 / 将分子除以分母 B/A=2 % 模数运算符,以及整数除法的余数 B%A=0 ++ 增加(递增)运算符,将整数值加一 A++=11 -- 相减(递减)运算符,将整数值减一 A—=9 二、Go语言 关系运算符 下表显示了Go语言支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 == 检查两个操作数的值是否相等,如果相等,则条件为真。 (A==B)结果为假 != 检查两个操作数的值是否相等,如果值不相等,则条件为真。 (A!=B)结果为真 > 检查左操作数的值是否大于右操作数的值,如果是,则条件为真。 (A>B)结果为假 < 检查左操作数的值是否小于右操作数的值,如果是,则条件为真。 (A<B)结果为真 >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件为真。 (A>=B)结果为假 <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件为真。 (A<=B)结果为真 三、Go语言 逻辑运算符 下表显示了Go语言支持的所有逻辑运算符。假设变量A的值为1,变量B的值为0,则: 运算符 描述 示例 && 逻辑AND运算符。如果两个操作数都不为零,则条件为真。 (A&&B)结果为真 || 逻辑OR运算符。如果两个操作数中的任何一个非零,则条件变为真。 (A||B)结果为真 ! 逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑非运算符将为假。 !(A&&B)结果为真 四、Go语言 位运算符 按位操作符对位进行操作,并执行逐位操作。 &,|和^的真值表如下: p q p&q p|q p^q 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1 假设A = 60, B = 13; 现在的二进制格式,如下: A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A|B = 0011 1101 A^B = 0011 0001 ~A = 1100 0011 Go语言支持的位运算符,如在下表中所列。 假设变量A=60,并且变量B=13,则: 运算符 描述 示例 & 如果两个操作数中都存在二进制AND运算符,则将其复制到结果。 (A&B)结果为12,也就是0000 1100 | 二进制OR运算符复制一个位,如果它存在于任一操作数。 (A|B)结果为61,也就是0011 1101 ^ 二进制XOR运算符复制位,如果它在一个操作数中设置,但不是在两个操作数中设置。 (A^B)结果为49,也就是0011 0001 << 二进制左移位运算符。左操作数值向左移动由右操作数指定的位数。 A<<2结果为240,也就是1111 0000 >> 二进制右移运算符。左操作数值向右移动由右操作数指定位数。 A>>2结果为15,也就是0000 1111 五、Go语言 赋值运算符 Go语言支持以下赋值运算符: 运算符 描述 示例 = 简单赋值操作符,将值从右侧操作数分配给左侧操作数 C=A+B,就是将A+B的值赋给C += 相加和赋值运算符,向左操作数添加右操作数,并将结果赋给左操作数 C+=A相当于C=C+A -= 减去和赋值运算符,从左操作数中减去右操作数,并将结果赋给左操作数 C-=A相当于C=C-A *= 乘法和赋值运算符,它将右操作数与左操作数相乘,并将结果赋给左操作数 C*=A相当于C=C*A /= 除法和赋值运算符,它用右操作数划分左操作数,并将结果分配给左操作数 C/=A相当于C=C/A %= 模数和赋值运算符,它使用两个操作数来取模,并将结果分配给左操作数 C%=A相当于C=C%A <<= 左移和赋值运算符 C<<=2相当于C=C<<2 >>= 右移和赋值运算符 C>>=2相当于C=C>>2 &= 按位和赋值运算符 C&=2相当于C=C&2 ^= 按位异或和赋值运算符 C^=2相当于C=C^2 |= 按位包含OR和赋值运算符 C|=2相当于C=C|2 六、Go语言 其他运算符 还有一些其他重要的运算符包括sizeof和? :,在Go语言中也是支持的。 运算符 描述 示例 & 返回变量的地址 &a将给出变量a的实际地址。 * 指向变量的指针 *a是指向变量a的指针。
Go语言 其他运算符
还有一些其他重要的运算符包括sizeof
和? :
,在Go语言中也是支持的。
运算符 | 描述 | 示例 |
---|---|---|
& | 返回变量的地址 |
&a 将给出变量a 的实际地址。 |
* | 指向变量的指针 |
*a 是指向变量a 的指针。 |
Go语言中的运算符优先级
运算符优先级确定表达式中的分组。这会影响表达式的计算方式。某些运算符比其他运算符具有更高的优先级; 例如,乘法运算符比加法运算符有更高的优先级。
当同级别的运算符出现在同一个表达式中,从左到右的顺序计算,比如乘除一起,不管是乘在前面还是除在前面都是从左到右计算乘、除运算符。加减亦是如此。
例如:x = 7 + 3 * 2
; 这里,计算结果x
被分配13
,而不是20
,因为运算符 *
具有比+
有更的优先级,所以它首先乘以3 * 2
,然后加上7
。
这里,具有最高优先级的运算符放在表的顶部,具有最低优先级的运算符出现在底部。 在表达式中,将首先计算较高优先级运算符。
分类 | 描述 | 关联性 |
---|---|---|
后缀 | ()[]->.++ -- | 左到右 |
一元 | + -!~++ --(type)*&sizeof | 右到左 |
乘法 | */ % | 左到右 |
加法 | + - | 左到右 |
移位 | <<>> | 左到右 |
关系 | <<=>>= | 左到右 |
相等 | ==!= | 左到右 |
按位AND | & | 左到右 |
按位XOR | ^ | 左到右 |
按位OR | | | 左到右 |
逻辑AND | && | 左到右 |
逻辑OR | || | 左到右 |
条件 | ?: | 右到左 |
分配 | =+=-=*=/= %=>>= <<= &= ^= |= | 右到左 |
逗号 | , | 左到右 |
if语句
多重判读结构
switch
for循环
range
package main import "fmt" // func test() (a, b, c int) { // return 1, 2, 3 // } func main() { a := "abcd" for i, data := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, data) } for i, _ := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, a[i]) } }
打印结果 xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d
break 和continue
和python一样
continue 只能用在循环理
break 只能用在 循环 switch select中
goto
无条件跳转(可以用在任何地方但是不能跨函数跳转)
go run go build的区别
程序基本语法
- 所有go源码以.go结尾;
- 注释不会被编译,单行注释是以 // 开头,多行注释以 /* 开头,以 */ 结尾;
- 标识符以字母或下划线开头,大小写敏感,_ 是特殊标识符,用来忽略结果;
- 保留关键字:
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 |
append | bool | byte | cap | close | complex | complex64 | complex128 | uint16 |
copy | false | float32 | float64 | imag | int | int8 | int16 | uint32 |
int32 | int64 | iota | len | make | new | nil | panic | uint64 |
println | real | recover | string | true | uint | uint8 | uintptr |
程序基本结构
1. 任何一个代码文件隶属于一个包
2. golang可执行程序,package main,并且有且只有一个main入口函数
3. 包中函数调用:
- 同一个包中函数,直接调用
- 不同包中函数,通过包名+点+函数名进行调用
4. 包访问控制规则:
- 大写意味着这个函数/变量是可导出的
- 小写意味着这个函数/变量是私有的,包外部不能访问
项目目录
$ tree project project ├── bin │ ├── example1 │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── day1 │ ├── example1 │ │ ├── debug │ │ └── hello.go │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender Src 源码文件 Bin 编译后二进制文件 vender 第三方 pkg 静态文件
简单栗子
$ tree project project ├── bin │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── test1 │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender
[main.go] package main import ( "fmt" "go_dev/test1/goroute_example/goroute" ) func main() { pipe := make(chan int, 1) go goroute.Add(pipe, 10, 20) sum := <-pipe fmt.Println(sum) }
[add.go] package goroute func Add(pipe chan int, a int, b int) { pipe <- (a + b) }
$ go build -o bin/goroute_example go_dev/test1/goroute_example/main $ bin/goroute_example 30 $
变量的声明和赋值
打印类型
fmt.Printf("sadf %T", c)
其他的打印方法不能使用 %T来打印类型
println和printf的区别
go println与printf区别 Println 与Printf 都是fmt 包中的公共方法 Println :可以打印出字符串,和变量; Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形, a := 10 fmt.Println(a) //right fmt.Println("abc") //right fmt.Printf("%d",a) //right fmt.Printf(a) //error %v 它可以以适当的格式输出任意的类型
常量的定义
const b = 10
不同类型的变量声明
枚举 iota
在常量中用
从0 开始 逐渐递增
字符和对应的ascci值的打印
字符和字符串的区别
格式输出
类型
【简介】 fmt 包实现了格式化 I/O 函数,类似于 C 的 printf 和 scanf。格式“占位符”衍生自 C,但比 C 更简单。 【打印】 占位符: [一般] %v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名 %#v 相应值的 Go 语法表示 %T 相应值的类型的 Go 语法表示 %% 字面上的百分号,并非值的占位符 [布尔] %t 单词 true 或 false。 [整数] %b 二进制表示 %c 相应 Unicode 码点所表示的字符 %d 十进制表示 %o 八进制表示 %q 单引号围绕的字符字面值,由 Go 语法安全地转义 %x 十六进制表示,字母形式为小写 a-f %X 十六进制表示,字母形式为大写 A-F %U Unicode 格式:U+1234,等同于 "U+%04X" [浮点数及其复合构成] %b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 的 'b' 转换格式一致。例如 -123456p-78 %e 科学计数法,例如 -1234.456e+78 %E 科学计数法,例如 -1234.456E+78 %f 有小数点而无指数,例如 123.456 %g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的 0)输出 %G 根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的 0)输出 [字符串与字节切片] %s 字符串或切片的无解译字节 %q 双引号围绕的字符串,由 Go 语法安全地转义 %x 十六进制,小写字母,每字节两个字符 %X 十六进制,大写字母,每字节两个字符 [指针] %p 十六进制表示,前缀 0x [注意]
格式化输入
scan 或者scanf
scan 不需要写入格式 自动匹配格式
类型转换
类型别名
给类型取别名,打印相应数据的类型会打印出类型的别名,也可以直接定义此别名类型的变量
运算符
Go语言运算符 Go语言运算符优先级,是描述在计算机运算计算表达式时执行运算的先后顺序。 先执行具有较高优先级的运算,然后执行较低优先级的运算。 例如,我们常说的先执行相乘和除,再执行加减运算。 Go 语言内置的运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 下面我们来对应Go语言各个运算符,算术、关系、逻辑、按位、赋值和其他运算符的详细讲解。 一、Go语言 算术运算符 下表显示了Go语言支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 + 添加两个操作数 A+B=30 - 从第一个操作数中减去第二个操作数 A-B=10 * 将两个操作数相乘 A*B=200 / 将分子除以分母 B/A=2 % 模数运算符,以及整数除法的余数 B%A=0 ++ 增加(递增)运算符,将整数值加一 A++=11 -- 相减(递减)运算符,将整数值减一 A—=9 二、Go语言 关系运算符 下表显示了Go语言支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 == 检查两个操作数的值是否相等,如果相等,则条件为真。 (A==B)结果为假 != 检查两个操作数的值是否相等,如果值不相等,则条件为真。 (A!=B)结果为真 > 检查左操作数的值是否大于右操作数的值,如果是,则条件为真。 (A>B)结果为假 < 检查左操作数的值是否小于右操作数的值,如果是,则条件为真。 (A<B)结果为真 >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件为真。 (A>=B)结果为假 <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件为真。 (A<=B)结果为真 三、Go语言 逻辑运算符 下表显示了Go语言支持的所有逻辑运算符。假设变量A的值为1,变量B的值为0,则: 运算符 描述 示例 && 逻辑AND运算符。如果两个操作数都不为零,则条件为真。 (A&&B)结果为真 || 逻辑OR运算符。如果两个操作数中的任何一个非零,则条件变为真。 (A||B)结果为真 ! 逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑非运算符将为假。 !(A&&B)结果为真 四、Go语言 位运算符 按位操作符对位进行操作,并执行逐位操作。 &,|和^的真值表如下: p q p&q p|q p^q 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1 假设A = 60, B = 13; 现在的二进制格式,如下: A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A|B = 0011 1101 A^B = 0011 0001 ~A = 1100 0011 Go语言支持的位运算符,如在下表中所列。 假设变量A=60,并且变量B=13,则: 运算符 描述 示例 & 如果两个操作数中都存在二进制AND运算符,则将其复制到结果。 (A&B)结果为12,也就是0000 1100 | 二进制OR运算符复制一个位,如果它存在于任一操作数。 (A|B)结果为61,也就是0011 1101 ^ 二进制XOR运算符复制位,如果它在一个操作数中设置,但不是在两个操作数中设置。 (A^B)结果为49,也就是0011 0001 << 二进制左移位运算符。左操作数值向左移动由右操作数指定的位数。 A<<2结果为240,也就是1111 0000 >> 二进制右移运算符。左操作数值向右移动由右操作数指定位数。 A>>2结果为15,也就是0000 1111 五、Go语言 赋值运算符 Go语言支持以下赋值运算符: 运算符 描述 示例 = 简单赋值操作符,将值从右侧操作数分配给左侧操作数 C=A+B,就是将A+B的值赋给C += 相加和赋值运算符,向左操作数添加右操作数,并将结果赋给左操作数 C+=A相当于C=C+A -= 减去和赋值运算符,从左操作数中减去右操作数,并将结果赋给左操作数 C-=A相当于C=C-A *= 乘法和赋值运算符,它将右操作数与左操作数相乘,并将结果赋给左操作数 C*=A相当于C=C*A /= 除法和赋值运算符,它用右操作数划分左操作数,并将结果分配给左操作数 C/=A相当于C=C/A %= 模数和赋值运算符,它使用两个操作数来取模,并将结果分配给左操作数 C%=A相当于C=C%A <<= 左移和赋值运算符 C<<=2相当于C=C<<2 >>= 右移和赋值运算符 C>>=2相当于C=C>>2 &= 按位和赋值运算符 C&=2相当于C=C&2 ^= 按位异或和赋值运算符 C^=2相当于C=C^2 |= 按位包含OR和赋值运算符 C|=2相当于C=C|2 六、Go语言 其他运算符 还有一些其他重要的运算符包括sizeof和? :,在Go语言中也是支持的。 运算符 描述 示例 & 返回变量的地址 &a将给出变量a的实际地址。 * 指向变量的指针 *a是指向变量a的指针。
Go语言 其他运算符
还有一些其他重要的运算符包括sizeof
和? :
,在Go语言中也是支持的。
运算符 | 描述 | 示例 |
---|---|---|
& | 返回变量的地址 |
&a 将给出变量a 的实际地址。 |
* | 指向变量的指针 |
*a 是指向变量a 的指针。 |
Go语言中的运算符优先级
运算符优先级确定表达式中的分组。这会影响表达式的计算方式。某些运算符比其他运算符具有更高的优先级; 例如,乘法运算符比加法运算符有更高的优先级。
当同级别的运算符出现在同一个表达式中,从左到右的顺序计算,比如乘除一起,不管是乘在前面还是除在前面都是从左到右计算乘、除运算符。加减亦是如此。
例如:x = 7 + 3 * 2
; 这里,计算结果x
被分配13
,而不是20
,因为运算符 *
具有比+
有更的优先级,所以它首先乘以3 * 2
,然后加上7
。
这里,具有最高优先级的运算符放在表的顶部,具有最低优先级的运算符出现在底部。 在表达式中,将首先计算较高优先级运算符。
分类 | 描述 | 关联性 |
---|---|---|
后缀 | ()[]->.++ -- | 左到右 |
一元 | + -!~++ --(type)*&sizeof | 右到左 |
乘法 | */ % | 左到右 |
加法 | + - | 左到右 |
移位 | <<>> | 左到右 |
关系 | <<=>>= | 左到右 |
相等 | ==!= | 左到右 |
按位AND | & | 左到右 |
按位XOR | ^ | 左到右 |
按位OR | | | 左到右 |
逻辑AND | && | 左到右 |
逻辑OR | || | 左到右 |
条件 | ?: | 右到左 |
分配 | =+=-=*=/= %=>>= <<= &= ^= |= | 右到左 |
逗号 | , | 左到右 |
if语句
多重判读结构
switch
for循环
range
package main import "fmt" // func test() (a, b, c int) { // return 1, 2, 3 // } func main() { a := "abcd" for i, data := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, data) } for i, _ := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, a[i]) } }
打印结果 xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d
break 和continue
和python一样
continue 只能用在循环理
break 只能用在 循环 switch select中
goto
无条件跳转(可以用在任何地方但是不能跨函数跳转)
1、Go有什么优势
- 可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
- 静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
- 语言层面支持并发,这个就是Go最大的特色,天生的支持并发,我曾经说过一句话,天生的基因和整容是有区别的,大家一样美丽,但是你喜欢整容的还是天生基因的美丽呢?Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
- 内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
- 简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
- 丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大,我最爱的也是这部分。
- 内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
- 跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
- 内嵌C支持,前面说了作者是C的作者,所以Go里面也可以直接包含c代码,利用现有的丰富的C库。
2、Go适合用来做什么
- 服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
- 分布式系统,数据库代理器等
- 网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用、
- 内存数据库,前一段时间google开发的groupcache,couchbase的部分组建
- 云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。
3、Go成功的项目
nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息
docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
skynet:分布式调度框架
Doozer:分布式同步工具,类似ZooKeeper
Heka:mazila开源的日志处理系统
cbfs:couchbase开源的分布式文件系统
tsuru:开源的PAAS平台,和SAE实现的功能一模一样
groupcache:memcahe作者写的用于Google下载系统的缓存系统
god:类似redis的缓存系统,但是支持分布式和扩展性
gor:网络流量抓包和重放工具
以下是一些公司,只是一小部分:
- http://Apcera.com
- http://Stathat.com
- Juju at Canonical/Ubuntu, presentation
- http://Beachfront.iO at Beachfront Media
- CloudFlare
- Soundcloud
- Mozilla
- Disqus
- http://Bit.ly
- Heroku
- youtube
学习地址 :点我
变量的声明和赋值
go run go build的区别
程序基本语法
- 所有go源码以.go结尾;
- 注释不会被编译,单行注释是以 // 开头,多行注释以 /* 开头,以 */ 结尾;
- 标识符以字母或下划线开头,大小写敏感,_ 是特殊标识符,用来忽略结果;
- 保留关键字:
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 |
append | bool | byte | cap | close | complex | complex64 | complex128 | uint16 |
copy | false | float32 | float64 | imag | int | int8 | int16 | uint32 |
int32 | int64 | iota | len | make | new | nil | panic | uint64 |
println | real | recover | string | true | uint | uint8 | uintptr |
程序基本结构
1. 任何一个代码文件隶属于一个包
2. golang可执行程序,package main,并且有且只有一个main入口函数
3. 包中函数调用:
- 同一个包中函数,直接调用
- 不同包中函数,通过包名+点+函数名进行调用
4. 包访问控制规则:
- 大写意味着这个函数/变量是可导出的
- 小写意味着这个函数/变量是私有的,包外部不能访问
项目目录
$ tree project project ├── bin │ ├── example1 │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── day1 │ ├── example1 │ │ ├── debug │ │ └── hello.go │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender Src 源码文件 Bin 编译后二进制文件 vender 第三方 pkg 静态文件
简单栗子
$ tree project project ├── bin │ └── goroute_example ├── pkg ├── src │ └── go_dev │ └── test1 │ └── goroute_example │ ├── goroute │ │ └── add.go │ └── main │ └── main.go └── vender
[main.go] package main import ( "fmt" "go_dev/test1/goroute_example/goroute" ) func main() { pipe := make(chan int, 1) go goroute.Add(pipe, 10, 20) sum := <-pipe fmt.Println(sum) }
[add.go] package goroute func Add(pipe chan int, a int, b int) { pipe <- (a + b) }
$ go build -o bin/goroute_example go_dev/test1/goroute_example/main $ bin/goroute_example 30 $
变量的声明和赋值
打印类型
fmt.Printf("sadf %T", c)
其他的打印方法不能使用 %T来打印类型
println和printf的区别
go println与printf区别 Println 与Printf 都是fmt 包中的公共方法 Println :可以打印出字符串,和变量; Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形, a := 10 fmt.Println(a) //right fmt.Println("abc") //right fmt.Printf("%d",a) //right fmt.Printf(a) //error %v 它可以以适当的格式输出任意的类型
常量的定义
const b = 10
不同类型的变量声明
枚举 iota
在常量中用
从0 开始 逐渐递增
字符和对应的ascci值的打印
字符和字符串的区别
格式输出
类型
【简介】 fmt 包实现了格式化 I/O 函数,类似于 C 的 printf 和 scanf。格式“占位符”衍生自 C,但比 C 更简单。 【打印】 占位符: [一般] %v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名 %#v 相应值的 Go 语法表示 %T 相应值的类型的 Go 语法表示 %% 字面上的百分号,并非值的占位符 [布尔] %t 单词 true 或 false。 [整数] %b 二进制表示 %c 相应 Unicode 码点所表示的字符 %d 十进制表示 %o 八进制表示 %q 单引号围绕的字符字面值,由 Go 语法安全地转义 %x 十六进制表示,字母形式为小写 a-f %X 十六进制表示,字母形式为大写 A-F %U Unicode 格式:U+1234,等同于 "U+%04X" [浮点数及其复合构成] %b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 的 'b' 转换格式一致。例如 -123456p-78 %e 科学计数法,例如 -1234.456e+78 %E 科学计数法,例如 -1234.456E+78 %f 有小数点而无指数,例如 123.456 %g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的 0)输出 %G 根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的 0)输出 [字符串与字节切片] %s 字符串或切片的无解译字节 %q 双引号围绕的字符串,由 Go 语法安全地转义 %x 十六进制,小写字母,每字节两个字符 %X 十六进制,大写字母,每字节两个字符 [指针] %p 十六进制表示,前缀 0x [注意]
格式化输入
scan 或者scanf
scan 不需要写入格式 自动匹配格式
类型转换
类型别名
给类型取别名,打印相应数据的类型会打印出类型的别名,也可以直接定义此别名类型的变量
运算符
Go语言运算符 Go语言运算符优先级,是描述在计算机运算计算表达式时执行运算的先后顺序。 先执行具有较高优先级的运算,然后执行较低优先级的运算。 例如,我们常说的先执行相乘和除,再执行加减运算。 Go 语言内置的运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 下面我们来对应Go语言各个运算符,算术、关系、逻辑、按位、赋值和其他运算符的详细讲解。 一、Go语言 算术运算符 下表显示了Go语言支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 + 添加两个操作数 A+B=30 - 从第一个操作数中减去第二个操作数 A-B=10 * 将两个操作数相乘 A*B=200 / 将分子除以分母 B/A=2 % 模数运算符,以及整数除法的余数 B%A=0 ++ 增加(递增)运算符,将整数值加一 A++=11 -- 相减(递减)运算符,将整数值减一 A—=9 二、Go语言 关系运算符 下表显示了Go语言支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则: 运算符 描述 示例 == 检查两个操作数的值是否相等,如果相等,则条件为真。 (A==B)结果为假 != 检查两个操作数的值是否相等,如果值不相等,则条件为真。 (A!=B)结果为真 > 检查左操作数的值是否大于右操作数的值,如果是,则条件为真。 (A>B)结果为假 < 检查左操作数的值是否小于右操作数的值,如果是,则条件为真。 (A<B)结果为真 >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件为真。 (A>=B)结果为假 <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件为真。 (A<=B)结果为真 三、Go语言 逻辑运算符 下表显示了Go语言支持的所有逻辑运算符。假设变量A的值为1,变量B的值为0,则: 运算符 描述 示例 && 逻辑AND运算符。如果两个操作数都不为零,则条件为真。 (A&&B)结果为真 || 逻辑OR运算符。如果两个操作数中的任何一个非零,则条件变为真。 (A||B)结果为真 ! 逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑非运算符将为假。 !(A&&B)结果为真 四、Go语言 位运算符 按位操作符对位进行操作,并执行逐位操作。 &,|和^的真值表如下: p q p&q p|q p^q 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1 假设A = 60, B = 13; 现在的二进制格式,如下: A = 0011 1100 B = 0000 1101 ----------------- A&B = 0000 1100 A|B = 0011 1101 A^B = 0011 0001 ~A = 1100 0011 Go语言支持的位运算符,如在下表中所列。 假设变量A=60,并且变量B=13,则: 运算符 描述 示例 & 如果两个操作数中都存在二进制AND运算符,则将其复制到结果。 (A&B)结果为12,也就是0000 1100 | 二进制OR运算符复制一个位,如果它存在于任一操作数。 (A|B)结果为61,也就是0011 1101 ^ 二进制XOR运算符复制位,如果它在一个操作数中设置,但不是在两个操作数中设置。 (A^B)结果为49,也就是0011 0001 << 二进制左移位运算符。左操作数值向左移动由右操作数指定的位数。 A<<2结果为240,也就是1111 0000 >> 二进制右移运算符。左操作数值向右移动由右操作数指定位数。 A>>2结果为15,也就是0000 1111 五、Go语言 赋值运算符 Go语言支持以下赋值运算符: 运算符 描述 示例 = 简单赋值操作符,将值从右侧操作数分配给左侧操作数 C=A+B,就是将A+B的值赋给C += 相加和赋值运算符,向左操作数添加右操作数,并将结果赋给左操作数 C+=A相当于C=C+A -= 减去和赋值运算符,从左操作数中减去右操作数,并将结果赋给左操作数 C-=A相当于C=C-A *= 乘法和赋值运算符,它将右操作数与左操作数相乘,并将结果赋给左操作数 C*=A相当于C=C*A /= 除法和赋值运算符,它用右操作数划分左操作数,并将结果分配给左操作数 C/=A相当于C=C/A %= 模数和赋值运算符,它使用两个操作数来取模,并将结果分配给左操作数 C%=A相当于C=C%A <<= 左移和赋值运算符 C<<=2相当于C=C<<2 >>= 右移和赋值运算符 C>>=2相当于C=C>>2 &= 按位和赋值运算符 C&=2相当于C=C&2 ^= 按位异或和赋值运算符 C^=2相当于C=C^2 |= 按位包含OR和赋值运算符 C|=2相当于C=C|2 六、Go语言 其他运算符 还有一些其他重要的运算符包括sizeof和? :,在Go语言中也是支持的。 运算符 描述 示例 & 返回变量的地址 &a将给出变量a的实际地址。 * 指向变量的指针 *a是指向变量a的指针。
Go语言 其他运算符
还有一些其他重要的运算符包括sizeof
和? :
,在Go语言中也是支持的。
运算符 | 描述 | 示例 |
---|---|---|
& | 返回变量的地址 |
&a 将给出变量a 的实际地址。 |
* | 指向变量的指针 |
*a 是指向变量a 的指针。 |
Go语言中的运算符优先级
运算符优先级确定表达式中的分组。这会影响表达式的计算方式。某些运算符比其他运算符具有更高的优先级; 例如,乘法运算符比加法运算符有更高的优先级。
当同级别的运算符出现在同一个表达式中,从左到右的顺序计算,比如乘除一起,不管是乘在前面还是除在前面都是从左到右计算乘、除运算符。加减亦是如此。
例如:x = 7 + 3 * 2
; 这里,计算结果x
被分配13
,而不是20
,因为运算符 *
具有比+
有更的优先级,所以它首先乘以3 * 2
,然后加上7
。
这里,具有最高优先级的运算符放在表的顶部,具有最低优先级的运算符出现在底部。 在表达式中,将首先计算较高优先级运算符。
分类 | 描述 | 关联性 |
---|---|---|
后缀 | ()[]->.++ -- | 左到右 |
一元 | + -!~++ --(type)*&sizeof | 右到左 |
乘法 | */ % | 左到右 |
加法 | + - | 左到右 |
移位 | <<>> | 左到右 |
关系 | <<=>>= | 左到右 |
相等 | ==!= | 左到右 |
按位AND | & | 左到右 |
按位XOR | ^ | 左到右 |
按位OR | | | 左到右 |
逻辑AND | && | 左到右 |
逻辑OR | || | 左到右 |
条件 | ?: | 右到左 |
分配 | =+=-=*=/= %=>>= <<= &= ^= |= | 右到左 |
逗号 | , | 左到右 |
if语句
多重判读结构
switch
for循环
range
package main import "fmt" // func test() (a, b, c int) { // return 1, 2, 3 // } func main() { a := "abcd" for i, data := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, data) } for i, _ := range a { fmt.Printf("xiabiao %d and zfu is %c\n", i, a[i]) } }
打印结果 xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d xiabiao 0 and zfu is a xiabiao 1 and zfu is b xiabiao 2 and zfu is c xiabiao 3 and zfu is d
break 和continue
和python一样
continue 只能用在循环理
break 只能用在 循环 switch select中
goto
无条件跳转(可以用在任何地方但是不能跨函数跳转)