文本编辑工具gedit(Linux)/Notepad++ (Windows)/Fraise (Mac OS X)
安装了GoClipse 插件的Eclipse ,集成性做得很好;
Vim/Emacs,万能开发工具;
LiteIDE,一款专为Go语言开发的集成开发环境。
工程管理
Go命令行工具
调试
FMT 输出日志/gdb
语言
变量
1234567891011121314
var v1 int
var v2 string
var v3 [10] int // 数组
var v4 [] int // 数组切片
var v5 struct {
f int
}
var v6 *int // 指针
var v7 map [ string ] int // map ,key 为string 类型,value 为int 类型
var v8 func(a int ) int
var v1 int = 10
var v2 = 10 // 编译器自动推导出v2 的类型
v3 := 10 // 编译器自动推导出v3 的类型
var ch chan int
ch := make( chan int )
ch <- value
向channel写入数据通常会导致程序阻塞,直到有其他goroutine 从这个channel中读取数据。从channel中读取数据的语法是
value := <-ch
结构体(struct)
1234
type Rect struct {
x, y float64
width, height float64
}
接口(interface )
流程控制
1234567891011121314151617181920
if a < 5 {
return 0
} else {
return 1
}
switch i {
case 0:
fmt.Printf("0")
case 1:
fmt.Printf("1")
case 2:
fallthrough
case 3:
fmt.Printf("3")
case 4, 5, 6:
fmt.Printf("4, 5, 6")
default:
fmt.Printf("Default")
}
注意上面的switch语句里面没有break语句
123456789
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
a := []int {1, 2, 3, 4, 5, 6}
for i, j := 0, len(a) – 1; i < j; i, j = i + 1, j – 1 {
a[i], a[j] = a[j], a[i]
}
且go语言包含goto语句
函数
1234567891011
package mymath
import "errors"
func Add(a int , b int ) (ret int , err error) {
if a < 0 || b < 0 { // 假设这个函数只支持两个非负数字的加法
err= errors.New("Should be non-negative numbers!")
return
}
return a + b, nil // 支持多重返回值
}
不定参数类型
1234567
func myfunc(args ... int ) {
for _, arg := range args {
fmt.Println(arg)
}
}
n, _ := f.Read(buf)
闭包
12345678910111213141516171819202122
package main
import (
"fmt"
)
func main() {
var j int = 5
a := func()( func()) {
var i int = 10
return func () {
fmt.Printf("i, j: %d, %d\n", i, j)
}
}()
a()
j *= 2
a()
}
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
var a Integer = 1
if a.Less(2) {
fmt.Println(a, "Less 2")
}
在你需要修改对象的时候,才必须用指针。它不是Go语言的约束,而是一种自然约束。
举个例子:
1234
func (a *Integer) Add(b Integer) {
*a += b
}
a.Add(2)
值语义和引用语义
1234
var a = [3] int {1, 2, 3}
var b = a
b[1]++
fmt.Println(a, b)
Go语言中的大多数类型都基于值语义
基本类型:如byte、int 、bool、float32、float64和string等;
复合类型:如数组(array)、结构体(struct)和指针(pointer )等。
Go语言中有4个类型比较特别,看起来像引用类型
数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine )间的通信设施。
接口(interface ):对一组满足某个契约的类型的抽象。
结构体
123456789
type Rect struct {
x, y float64
width, height float64
}
// 初始化
rect1 := new (Rect)
rect2 := &Rect{}
rect3 := &Rect{0, 0, 100, 200}
rect4 := &Rect{width: 100, height: 200}
匿名组合:
12345678910111213141516
type Base struct {
Name string
}
func (base *Base) baseFoo() { ... }
func (base *Base) baseBar() { ... }
type Foo struct {
Base
...
}
func (foo *Foo) Bar() {
foo.Base.baseBar()
...
}
要使某个符号对其他包(package)可见(即可以访问),需要将该符号定义为以大写字母开头
接口
非侵入式接口:
将对象实例赋值给接口;将一个接口赋值给另一个接口。
我们定义一个Integer类型的对象实例,怎么将其赋值给LessAdder
12345678910111213141516
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
func (a *Integer) Add(b Integer) {
*a += b
}
type LessAdder interface {
Less(b Integer) bool
Add(b Integer)
}
var a Integer = 1
var b LessAdder = &a
下面的例子,定义了两个不同的包:
12345678910111213
package one
type ReadWriter interface {
Read(buf []byte) (n int , err error)
Write(buf [] byte) (n int , err error)
}
package two
type IStream interface {
Write(buf [] byte) (n int , err error)
Read(buf []byte) (n int , err error)
}
任何实现了one.ReadWriter接口的类,均实现了two.IStream ;
任何one.ReadWriter接口对象可赋值给two.IStream ,反之亦然;
在任何地方使用one.ReadWriter接口与使用two.IStream 并无差异。
以下这些代码可编译通过:
123
var file1 two.IStream = new (File)
var file2 one.ReadWriter = file1
var file3 two.IStream = file2
var v1 interface{} = 1 // 将int 类型赋值给interface{}
var v2 interface{} = "abc" // 将string类型赋值给interface{}
var v3 interface{} = &v2 // 将*interface{}类型赋值给interface{}
var v4 interface{} = struct { X int }{1}
var v5 interface{} = & struct { X int }{1}
生产者协程
loop
while q is not full
create some new items
add the items to q
yield to consume
消费者协程
loop
while q is not empty
remove some items from q
use the items
yield to produce
一个python的例子:
1234567891011
defh():print'Wen Chuan',m=yield5# Fighting!printmd=yield12print'We are together!'c=h()m=c.next()#m 获取了yield 5 的参数值 5d=c.send('Fighting!')#d 获取了yield 12 的参数值12print'We will never forget the date',m,'.',d
输出结果:
12
WenChuanFighting!Wewillneverforgetthedate5.12
Go 语言在语言级别支持轻量级线程,叫goroutine 。
一个函数调用前加上go关键字,这次调用就会在一个新的goroutine 中并发执行。当被调用的函数返回时,这个goroutine 也自动结束了。需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。