golang

golang

beego1.8版本功能征集

文章分享mnhkahn 回复了问题 • 17 人关注 • 20 个回复 • 1567 次浏览 • 19 分钟前 • 来自相关话题

println 与 fmt.Println 一起使用为何不是顺序打印?

Golangsongtianyi 回复了问题 • 4 人关注 • 4 个回复 • 174 次浏览 • 23 小时前 • 来自相关话题

处理文件上传的工具包 - fuh

开源程序lyric 发表了文章 • 0 个评论 • 74 次浏览 • 1 天前 • 来自相关话题

处理文件上传的工具包 - fuh

在平时web开发过程中,总会遇到处理文件上传的场景,每次的处理方式都是以业务为导向进行处理。现在作者就把这一... 查看全部

处理文件上传的工具包 - fuh


在平时web开发过程中,总会遇到处理文件上传的场景,每次的处理方式都是以业务为导向进行处理。现在作者就把这一块单独抽离出来,做成了一个简单的工具包。主要特点是:



  • 支持自定义文件存储

  • 支持自定义文件名

  • 支持自定义文件大小限制


引入简单,方便,欢迎来拍砖!谢谢!


$ go get github.com/LyricTian/fuh

package main

import (
"encoding/json"
"net/http"

"github.com/LyricTian/fuh"
)

func main() {
http.HandleFunc("/fileupload", func(w http.ResponseWriter, r *http.Request) {
finfo, err := fuh.Upload(r, "file", nil, nil)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
json.NewEncoder(w).Encode(finfo)
})

http.ListenAndServe(":8080", nil)
}

使用什么docker image来运行Go程序

有问必答zensh 回复了问题 • 13 人关注 • 13 个回复 • 845 次浏览 • 2 天前 • 来自相关话题

golang 的channel是否适合做消息队列?

有问必答pathbox 回复了问题 • 15 人关注 • 9 个回复 • 1631 次浏览 • 5 天前 • 来自相关话题

dockerSSH用ssh连接到docker

开源程序myml 发表了文章 • 3 个评论 • 91 次浏览 • 2017-02-11 21:59 • 来自相关话题

dockerSSH

用golang.org/x/crypto/ssh 实现的ssh服务器,能直接让你通过ss... 查看全部

dockerSSH


用golang.org/x/crypto/ssh 实现的ssh服务器,能直接让你通过ssh登陆到docker容器内,比如ssh ff756b3ea527@127.0.0.1 会登陆到ID为ff756b3ea527的容器,刚实现的尚不成熟,还有一些功能想去实现,比如scp,sftp

go怎么获取本机ip的疑问

有问必答Akagi201 回复了问题 • 6 人关注 • 4 个回复 • 328 次浏览 • 2017-02-09 18:43 • 来自相关话题

好玩的github项目-用go做个flappy bird

Go开源项目wwdyy 发表了文章 • 1 个评论 • 285 次浏览 • 2017-02-06 22:46 • 来自相关话题

flappy gopher

转自github用户neomede

A flappy bird clone made in go. 查看全部

flappy gopher


转自github用户neomede


A flappy bird clone made in go.


Based on this video and this project by Francesc Campoy, also this project by Sab


Play


Just run "make run" and use any button to jump


github地址:https://github.com/neomede/flappy

请问有golang实现的acc编码/解码库吗?

有问必答Akagi201 回复了问题 • 2 人关注 • 1 个回复 • 136 次浏览 • 2017-02-06 13:54 • 来自相关话题

Go Base64 Decode 的问题

有问必答皇虫 回复了问题 • 4 人关注 • 3 个回复 • 302 次浏览 • 2017-01-29 08:46 • 来自相关话题

golang 特性简介

文章分享sheepbao 发表了文章 • 0 个评论 • 421 次浏览 • 2017-01-22 16:37 • 来自相关话题

golang 特性简介

by sheepbao

主要大概介绍go语言的历史和特性,简单的入门。

来历

很久以前,有一个IT公司,这公司有个传统,允许员工拥有20... 查看全部

golang 特性简介


by sheepbao


主要大概介绍go语言的历史和特性,简单的入门。


来历


很久以前,有一个IT公司,这公司有个传统,允许员工拥有20%自由时间来开发实验性项目。在2007的某一天,公司的几个大牛,正在用c++开发一些比较繁琐但是核心的工作,主要包括庞大的分布式集群,大牛觉得很闹心,后来c++委员会来他们公司演讲,说c++将要添加大概35种新特性。这几个大牛的其中一个人,名为:Rob Pike,听后心中一万个xxx飘过,“c++特性还不够多吗?简化c++应该更有成就感吧”。于是乎,Rob Pike和其他几个大牛讨论了一下,怎么解决这个问题,过了一会,Rob Pike说要不我们自己搞个语言吧,名字叫“go”,非常简短,容易拼写。其他几位大牛就说好啊,然后他们找了块白板,在上面写下希望能有哪些功能(详见文尾)。接下来的时间里,大牛们开心的讨论设计这门语言的特性,经过漫长的岁月,他们决定,以c语言为原型,以及借鉴其他语言的一些特性,来解放程序员,解放自己,然后在2009年,go语言诞生。


思想


Less can be more


大道至简,小而蕴真


让事情变得复杂很容易,让事情变得简单才难


深刻的工程文化


优点



  1. 自带gc。

  2. 静态编译,编译好后,扔服务器直接运行。

  3. 简单的思想,没有继承,多态,类等。

  4. 丰富的库和详细的开发文档。

  5. 语法层支持并发,和拥有同步并发的channel类型,使并发开发变得非常方便。

  6. 简洁的语法,提高开发效率,同时提高代码的阅读性和可维护性。

  7. 超级简单的交叉编译,仅需更改环境变量。(花了我两天时间编译一个imagemagick到arm平台)

  8. 内含完善、全面的软件工程工具。Go语言自带的命令和工具相当地强大。通过它们,我们可以很轻松地完成Go语言程序的获取、编译、测试、安装、运行、运行分析等一系列工作,这几乎涉及了开发和维护一个软件的所有环节。


hello


package main

func main(){
println("hello, sewise")
}

type


主要讲讲特有的类型,其他基本类型不做介绍


slice


切片:可以理解为动态数组,类似c++的vector
声明一个slice


    var slice []T
如:
var ints []int

slice的追加


    ints=append(ints,1)
ints=append(ints,2,3,4,5)

slice的截取


    newInts1:=ints[2:3]
newInts2:=ints[2:]
newInts3:=ints[:4]

map


字典:键值对


    var json map[string]string

interface


接口:方法的集合,是一种合约
栗子:
声明一个bird接口


    var bird interface{
fly()
}

声明一个hen对象(实现bird接口)


    type hen struct {
weight int
hasFeather bool
}

func (h hen)fly(){
fmt.Println("iI can fly")
}

type func (h hen)eat(){
h.weight++
fmt.Println("yes, I can eat")
}

声明一个pig对象(未实现bird接口,因为pig不会fly)


    type pig struct {
age int
weignt int
hasFeather bool
}

func (p pig)run(){
fmt.Println("I can run")
}

func (p pig)eat(){
p.weight += 100
fmt.Println("Yes, I can eat so much")
}

func (p pig)sleep(){
fmt.Println("I slept all my life")
}

// pig can't fly

channel


通道:轻量集队列,传递某种类型的值的通道


    var ch chan int
ch=make(chan int,1)

往ch写入一个数据


    ch<-8888

从ch读取数据


    out:=<-ch

特性:
channel是有长度的,当channel的缓冲为满时,再往里写入就会阻塞,当channel的缓冲为空时,从channel读就会阻塞


package main

import (
"fmt"
"time"
)

func main() {
ch := make(chan int)
fmt.Println("ch len:", len(ch))
go func() {
// 往缓冲满的channel里写数据(阻塞)
// ch <- 1
// 从缓冲为空的channel里读数据(阻塞)
<-ch
fmt.Println("I am in minor goroutine")
}()
fmt.Println("I am in main goroutine")
time.Sleep(2 * time.Second)
}

当长度为0是,就是不带缓冲的channel
长度大于0,就是带缓冲的channel


并发


关键字:go 启动go程
一个普通的函数或方法调用前加上关键字go,即可启动一个goroutine


    go func(){
fmt.Println("start func")
time.Sleep(120*time.Second)
}()

竞争条件检测
-race
race.go


package main

import (
"fmt"
"time"
)

func main() {
a := 1
go func() {
a = 2
}()
a = 3
fmt.Println("a is ", a)

time.Sleep(2 * time.Second)
}

检测:执行go run -race race.go


a is  3
==================
WARNING: DATA RACE
Write at 0x00c420072188 by goroutine 6:
main.main.func1()
/Users/bao/program/go/gowork/hello/src/research/race.go:11 +0x3b

Previous write at 0x00c420072188 by main goroutine:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:13 +0x9f

Goroutine 6 (running) created at:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:12 +0x8e
==================
Found 1 data race(s)

结果分析:
goroutine6运行到第11行和main goroutine运行到13行的时候触发竞争了。而且goroutine6是在第12行的时候产生的。


package


包的管理,关键字importGOPATH


gopath


gopath是一个路径列表,存放go项目工程
GOPATH文件目录结构


├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录

平常项目的目录结构


├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录
├── main 入口函数目录
└── vendor 当前项目的库目录
└── sheepbao.com
└── glog

import


比如上面的项目,我要在main.go引入glog


package main

// 引入glog包
import "sheepbao.com/glog"

func main(){
glog.Println("test")
}

go的工程工具简介


test


go的命令工具 test,用来做测试


单元测试


go test
只测试函数名被它正确匹配的测试函数
go test -v -run="French|Canal"


栗子:
add.go


package test

func addOne(i int) int {
return i + 1
}

add_test.go


package test

import "testing"

func TestAddOne(t *testing.T) {
result := addOne(1)
if result != 2 {
t.Error("1+1!=2")
}
}

bao@baoMac test$ go test -v .
=== RUN TestAddOne
--- PASS: TestAddOne (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/test 0.006s

基准测试


go test -bench=.
内存的分配情况
go test -bench=FuncName -benchmem
栗子:
stringsCon.go


package bench

import (
"fmt"
)

func Sprintf(s1, s2, s3 string) string {
return fmt.Sprintf("%s%s%s", s1, s2, s3)
}

func AddString(s1, s2, s3 string) string {
return s1 + s2 + s3
}

stringCon_test.go


package bench

import "testing"

var (
s1 = "make it run!"
s2 = "make it right!"
s3 = "make it fast!"
)

func BenchmarkSprintf(b *testing.B) {
for i := 0; i < b.N; i++ {
Sprintf(s1, s2, s3)
}
}

func BenchmarkAddString(b *testing.B) {
for i := 0; i < b.N; i++ {
AddString(s1, s2, s3)
}
}

go test -bench=.


bao@baoMac bench$ go test -bench=.
testing: warning: no tests to run
BenchmarkSprintf-4 5000000 349 ns/op
BenchmarkAddString-4 20000000 61.7 ns/op
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/bench 3.414s

样本测试


package et

import (
"fmt"
)

func ExampleHello() {
fmt.Println("hello, sewise")
// Output: hello, sewise
}

bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- PASS: ExampleHello (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

如果把上面的// Output: hello, sewise改为// Output: hello, sewis
则样本测试不能通过


bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- FAIL: ExampleHello (0.00s)
got:
hello, sewise
want:
hello, sewis
FAIL
exit status 1
FAIL _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

pprof


go的命令工具 pprof,用来性能分析(内存使用,泄露和cpu消耗)
go tool pprof



可视化(原是svg文件,下图为截图):


image_1b72f233avto14d7on4h3nlm51g.png-129.8kB



可视化(原是svg文件,下图为截图:


image_1b72euk7b1knr1d1n1ugq2pe19kim.png-176.7kB


go tool pprof --text http://localhost:6060/debug/pprof/heap


go命令教程


资料


http://www.csdn.net/article/2012-07-04/2807113-less-is-exponentially-more


http://www.jianshu.com/p/91e40c3e3acb?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io


http://smallsoho.com/2016/11/20/Go简明教程.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io


大牛真身


最大牌的当属B和C语言设计者、Unix和Plan 9创始人、1983年图灵奖获得者Ken Thompson,这份名单中还包括了Unix核心成员Rob Pike(go语言之父)、java HotSpot虚拟机和js v8引擎的开发者Robert Griesemer、Memcached作者Brad Fitzpatrick,等等。


功能



  • 规范的语法(不需要符号表来解析)

  • 垃圾回收(独有)

  • 无头文件

  • 明确的依赖

  • 无循环依赖

  • 常量只能是数字

  • int和int32是两种类型

  • 字母大小写设置可见性(letter case sets visibility)

  • 任何类型(type)都有方法(不是类型)

  • 没有子类型继承(不是子类)

  • 包级别初始化以及明确的初始化顺序

  • 文件被编译到一个包里

  • 包package-level globals presented in any order

  • 没有数值类型转换(常量起辅助作用)

  • 接口隐式实现(没有“implement”声明)

  • 嵌入(不会提升到超类)

  • 方法按照函数声明(没有特别的位置要求)

  • 方法即函数

  • 接口只有方法(没有数据)

  • 方法通过名字匹配(而非类型)

  • 没有构造函数和析构函数

  • postincrement(如++i)是状态,不是表达式

  • 没有preincrement(i++)和predecrement

  • 赋值不是表达式

  • 明确赋值和函数调用中的计算顺序(没有“sequence point”)

  • 没有指针运算

  • 内存一直以零值初始化

  • 局部变量取值合法

  • 方法中没有“this”

  • 分段的堆栈

  • 没有静态和其它类型的注释

  • 没有模板

  • 内建string、slice和map

  • 数组边界检查

go原生的RPC的文档资料,在哪里看啊

有问必答codinghxl 回复了问题 • 6 人关注 • 7 个回复 • 730 次浏览 • 2017-01-21 08:26 • 来自相关话题

gmcache一个用go写的分布式缓存,类似memcached

开源程序stirlingx 发表了文章 • 0 个评论 • 220 次浏览 • 2017-01-19 16:01 • 来自相关话题

主要是用来练手的,欢迎大家仍砖头

  • 使用ectd做服务发现
  • broker作为代理服务器,对client的请求做转发,用一致性hash算法对key映射到后端gmcache。

项目地... 查看全部

主要是用来练手的,欢迎大家仍砖头



  • 使用ectd做服务发现

  • broker作为代理服务器,对client的请求做转发,用一致性hash算法对key映射到后端gmcache。


项目地址:


https://github.com/liyue201/gmcache


Gmcache


A distributed key/value memory cache written in go.


Features



  • Light weight

  • Pure golang

  • Supports set,get and delete

  • Supports grpc and http protocols

  • Scalable architecture


Architecture


gmcache-cluster

Go 通过 Swig 调用 C/C++ 程序

技术讨论Akagi201 发表了文章 • 1 个评论 • 205 次浏览 • 2017-01-18 21:08 • 来自相关话题

项目地址: https://github.com/Akagi201/swiggo


swiggo


Build Status
Go Report Card
GoDoc


Call C/C++ lib with the help of swig


Generate Go package file and C/C++ wrapper file



  • mv interface.swig/interface.swigxx interface.i

  • For C: swig -go -cgo -intgosize 64 interface.i

  • For C++: swig -go -cgo -c++ -intgosize 64 interface.i


Usage



  • go get github.com/Akagi201/swiggo


TODO



  • [ ] Auto gen Go package files for godoc and IDE to browser Go definitions.

条新动态, 点击查看
bigwhite

bigwhite 回答了问题 • 2016-10-11 13:03 • 8 个回复 不感兴趣

怎么学习golang?

赞同来自:

记得早期接触go时,看的是Golang之父之一的Rob Pike的Go course 3部曲(3个ppt),如果你没有,可以到[这里](https://pan.baidu.com/s/1miFEDJy)下载(注意:由于rob pike的这个ppt在go 1之前... 显示全部 »
记得早期接触go时,看的是Golang之父之一的Rob Pike的Go course 3部曲(3个ppt),如果你没有,可以到[这里](https://pan.baidu.com/s/1miFEDJy)下载(注意:由于rob pike的这个ppt在go 1之前发布的,ppt上的有些语法与go 1有少许差别,注意识别)。

要想深入了解Go,写出idiomatic的golang代码,官方doc:effective go, go faq,以及go language specification也是不可或缺的。

之后再系统的学习后的资料,建议看k&a写的go圣经-the go programming language、
《Go in action》 以及国内雨痕大师的《go语言学习笔记》(尤其是代码分析的部分),学习笔记一书适合稍微有些go经验,且抱着极大热情挖掘go runtime背后的原理的人去学习。

剩下的就是不断的去用go coding, coding, coding了,无捷径。
astaxie

astaxie 回答了问题 • 2016-10-11 21:41 • 9 个回复 不感兴趣

golang 的channel是否适合做消息队列?

赞同来自:

我猜你看到的文章的担心是万一程序挂了怎么办,在缓冲channel里面的数据就可能丢失了,如果这个是可以忍受的话其实是非常适合做消息队列的
我猜你看到的文章的担心是万一程序挂了怎么办,在缓冲channel里面的数据就可能丢失了,如果这个是可以忍受的话其实是非常适合做消息队列的
name5566

name5566 回答了问题 • 2016-10-12 11:36 • 8 个回复 不感兴趣

golang有没有好的开源游戏框架

赞同来自:

> 使用 Leaf 已知的上线项目:
> * 2014 年,某手游(棋牌)项目上线
> * 2016 年,某 H5 手游项目上线
> * 2016 年,某卡牌手游项目上线
> 正在研发项目 N 个,已知情况 N >= 4

... 显示全部 »
> 使用 Leaf 已知的上线项目:
> * 2014 年,某手游(棋牌)项目上线
> * 2016 年,某 H5 手游项目上线
> * 2016 年,某卡牌手游项目上线
> 正在研发项目 N 个,已知情况 N >= 4

来自:https://github.com/name5566/leaf/wiki
leoliu

leoliu 回答了问题 • 2016-10-12 13:44 • 22 个回复 不感兴趣

求一些golang的教程,书籍也可以

赞同来自:

《The Golang Programming Language》
《Golang 学习笔记》
《The Golang Programming Language》
《Golang 学习笔记》
yougg

yougg 回答了问题 • 2016-10-14 10:01 • 70 个回复 不感兴趣

大家说说看都用啥写Go

赞同来自:

# IDEA大法好
# 天灭vscode 退软保平安
# 人在做,天在看 中文乱码留祸患
# 界面卡顿天地灭 赶紧卸载保平安
# 诚心诚念IDEA好 JetBrains大法平安保
# 众生皆为IDEA来 现世险恶忘前缘
# 开源为你说真相 教你脱险莫拒绝
# ... 显示全部 »
# IDEA大法好
# 天灭vscode 退软保平安
# 人在做,天在看 中文乱码留祸患
# 界面卡顿天地灭 赶紧卸载保平安
# 诚心诚念IDEA好 JetBrains大法平安保
# 众生皆为IDEA来 现世险恶忘前缘
# 开源为你说真相 教你脱险莫拒绝
# 早日不做软粉,早日获得新生
# 上网搜索“九评纳德拉”
# 有 真 相
sryan

sryan 回答了问题 • 2016-10-13 11:44 • 7 个回复 不感兴趣

golang 如何动态创建struct

赞同来自:

静态语言貌似不能直接实现
可以自己实现个map[string]func(string)interface{}
将要动态生成的结构体的函数注册上去
通过string来调用相应的函数来获取对应的结构体
静态语言貌似不能直接实现
可以自己实现个map[string]func(string)interface{}
将要动态生成的结构体的函数注册上去
通过string来调用相应的函数来获取对应的结构体
astaxie

astaxie 回答了问题 • 2016-10-13 22:04 • 12 个回复 不感兴趣

想用golang写个分布式的监控,大神给点建议

赞同来自:

这个问题很有意思,很多场景设计都会来考虑拉和推两种方案,我分别对拉和推两种的优缺点对比以下,你自己权衡一下,欢迎大家继续补充

## 拉的方案(不写agent)
优点:
- 不需要agent,不需要再部署新的程序

缺点:
- 网络中断的情况下,就无法监控机器... 显示全部 »
这个问题很有意思,很多场景设计都会来考虑拉和推两种方案,我分别对拉和推两种的优缺点对比以下,你自己权衡一下,欢迎大家继续补充

## 拉的方案(不写agent)
优点:
- 不需要agent,不需要再部署新的程序

缺点:
- 网络中断的情况下,就无法监控机器的信息

## 推的方案(agent)
优点:
- 本地运行,在和中控机失去网络连接的时候还是可以继续保存监控数据

缺点:
- 需要部署agent,如果机器多得话将来升级也是比较麻烦

拉取和推送其实大家可以考虑,微博的follow逻辑,直播流里面也有同样的问题,很多场景都会遇到

至于说第二种方案走什么协议,这种程序我建议走tcp协议,HTTP的话相对重了一点。
sheepbao

sheepbao 回答了问题 • 2016-10-30 20:16 • 12 个回复 不感兴趣

字符串连接哪一种方式最高效

赞同来自:

```go
package main

import (
"bytes"
"fmt"
"strings"
"time"
)

var way map[int]string
... 显示全部 »
```go
package main

import (
"bytes"
"fmt"
"strings"
"time"
)

var way map[int]string

func benchmarkStringFunction(n int, index int) (d time.Duration) {
v := "ni shuo wo shi bu shi tai wu liao le a?"
var s string
var buf bytes.Buffer

t0 := time.Now()
for i := 0; i < n; i++ {
switch index {
case 0: // fmt.Sprintf
s = fmt.Sprintf("%s[%s]", s, v)
case 1: // string +
s = s + "[" + v + "]"
case 2: // strings.Join
s = strings.Join([]string{s, "[", v, "]"}, "")
case 3: // stable bytes.Buffer
buf.WriteString("[")
buf.WriteString(v)
buf.WriteString("]")
}

}
d = time.Since(t0)
if index == 3 {
s = buf.String()
}
fmt.Printf("string len: %d\t", len(s))
fmt.Printf("time of [%s]=\t %v\n", way[index], d)
return d
}

func main() {
way = make(map[int]string, 5)
way[0] = "fmt.Sprintf"
way[1] = "+"
way[2] = "strings.Join"
way[3] = "bytes.Buffer"

k := 4
d := [5]time.Duration{}
for i := 0; i < k; i++ {
d[i] = benchmarkStringFunction(10000, i)
}
}

```
结果:
```
string len: 410000 time of [fmt.Sprintf]= 426.001476ms
string len: 410000 time of [+]= 307.044147ms
string len: 410000 time of [strings.Join]= 738.44362ms
string len: 410000 time of [bytes.Buffer]= 742.248µs
```
* strings.Join 最慢
* fmt.Sprintf 和 string + 差不多
* bytes.Buffer又比上者快约500倍
CodyGuo

CodyGuo 回答了问题 • 2016-10-30 12:57 • 4 个回复 不感兴趣

Go里面如何写多行的字符串吗?

赞同来自:

```go
`line 1
line 2
line 3`
```
```go
`line 1
line 2
line 3`
```
philosophia14

philosophia14 回答了问题 • 2016-11-05 00:30 • 3 个回复 不感兴趣

新版本Go将会对database/sql进行大量改进

赞同来自:

但愿不要多改..
但愿不要多改..
zdreamx

zdreamx 回答了问题 • 2016-11-08 11:27 • 20 个回复 不感兴趣

beego1.8版本功能征集

赞同来自:

orm有没有考虑分表分区分库的优化或支持
orm有没有考虑分表分区分库的优化或支持
println 是把结果输出到 standard error

fmt.Println 是把结果输出到 standard output
println 是把结果输出到 standard error

fmt.Println 是把结果输出到 standard output

大家是如何处理 golang web 应用静态资源的?

技术讨论astaxie 回复了问题 • 4 人关注 • 1 个回复 • 453 次浏览 • 2016-10-14 13:08 • 来自相关话题

Python 程序员的 Golang 学习指南(II): 开发环境搭建

文章分享Cloudinsight 发表了文章 • 0 个评论 • 640 次浏览 • 2016-10-12 15:44 • 来自相关话题

Authors: startover

Authors: startover





上一篇文章我们已经对 Golang 有了初步的了解,这篇主要介绍如何在 Ubuntu 14.04 上搭建 Golang 开发环境。


安装 Golang


这里就按照官方文档进行安装即可,如下:



  • 下载并解压安装包到指定目录


$ wget https://storage.googleapis.com ... ar.gz
$ tar -C /usr/local -xzf go1.6.3.linux-amd64.tar.gz


  • 设置 PATH


$ echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
$ source ~/.bashrc


  • 验证安装


$ go version
go version go1.6.3 linux/amd64

环境变量设置


$ echo "export GOROOT=/usr/local/go" >> ~/.bashrc
$ echo "export GOPATH=$HOME/go" >> ~/.bashrc
$ source ~/.bashrc

其中,GOROOT 为 Golang 的安装目录,只有当 Golang 安装到除 /usr/local 之外的路径时需要设置,反之则不用设置,GOPATH 是 Golang 的开发目录,详细可参考官方文档


开发工具


工欲善其事,必先利其器,作为一名伪 VIMer,这里主要介绍下如何在 Vim 下配置 Golang 开发环境。


由于之前一直使用 k-vim 作为 Python 开发环境,而 k-vim 已经集成了当前使用最为广泛的用于搭建 Golang 开发环境的 vim 插件 vim-go,只是默认没有开启,需要我们手动进行相关设置。


k-vim 中开启 Golang 语言的支持,非常简单,如下:



  • 修改 ~/.vimrc.bundles(开启 golang 支持,并修改 vim-go 的默认配置,增加快捷键配置等)。


let g:bundle_groups=['python', 'javascript', 'markdown', 'html', 'css', 'tmux', 'beta', 'json', 'golang']

" vimgo {{{
let g:go_highlight_functions = 1
let g:go_highlight_methods = 1
let g:go_highlight_structs = 1
let g:go_highlight_operators = 1
let g:go_highlight_build_constraints = 1

let g:go_fmt_fail_silently = 1
let g:go_fmt_command = "goimports"
let g:syntastic_go_checkers = ['golint', 'govet', 'errcheck']

" vim-go custom mappings
au FileType go nmap <Leader>s <Plug>(go-implements)
au FileType go nmap <Leader>i <Plug>(go-info)
au FileType go nmap <Leader>gd <Plug>(go-doc)
au FileType go nmap <Leader>gv <Plug>(go-doc-vertical)
au FileType go nmap <leader>r <Plug>(go-run)
au FileType go nmap <leader>b <Plug>(go-build)
au FileType go nmap <leader>t <Plug>(go-test)
au FileType go nmap <leader>c <Plug>(go-coverage)
au FileType go nmap <Leader>ds <Plug>(go-def-split)
au FileType go nmap <Leader>dv <Plug>(go-def-vertical)
au FileType go nmap <Leader>dt <Plug>(go-def-tab)
au FileType go nmap <Leader>e <Plug>(go-rename)
au FileType go nnoremap <leader>gr :GoRun %<CR>
" }}}



  • 在 Vim 内执行 :PlugInstall,安装 vim-go




  • 在 Vim 内执行 :GoInstallBinaries,下载并安装 vim-go 依赖的二进制工具,goimportsgolint 等。



  • 安装 gotags,使 tagbar 配置生效。


$ go get -u github.com/jstemmer/gotags

我们来看一下最终效果:


Image of Golang Environment in Vim


编写第一个程序


进入工作目录,新建文件 hello.go,如下:


$ cd $GOPATH
$ vim hello.go
package main

import "fmt"

func main() {
fmt.Println("Hello, World!")
}

运行程序:


$ go run hello.go
Hello, World!



本文章为 Cloudinsight 技术团队工程师原创,更多技术文章可访问 Cloudinsight 技术博客Cloudinsight 为可视化系统监控工具,涵盖 Windows、Linux 操作系统,用 Golang 开发的 Cloudinsight Agent 正式开源了,欢迎 fork,Github:https://github.com/cloudinsight/cloudinsight-agent


golang-for-pythonistas 系列持续更新中,欢迎关注~

Python 程序员的 Golang 学习指南(I): Go 之初体验

文章分享Cloudinsight 发表了文章 • 2 个评论 • 665 次浏览 • 2016-10-12 15:27 • 来自相关话题

Authors: startover

Authors: startover





Go 语言简介


Go,又称 golang,是 Google 开发的一种静态强类型,编译型,并发型,并具有垃圾回收功能的编程语言。


Go 语言于2009年11月正式宣布推出,自2012年发布1.0,最新稳定版1.7。目前,Go的相关工具和生态已逐渐趋于完善,也不乏重量级项目,如 Docker, Kubernetes, Etcd, InfluxDB 等。


Go 语言能解决什么样的问题


同绝大多数通用型编程语言相比,Go 语言更多的是为了解决我们在构建大型服务器软件过程中所遇到的软件工程方面的问题而设计的。乍看上去,这么讲可能会让人感觉 Go 非常无趣且工业化,但实际上,在设计过程中就着重于清晰和简洁,以及较高的可组合性,最后得到的反而会是一门使用起来效率高而且很有趣的编程语言,很多程序员都会发现,它有极强的表达力而且功能非常强大。


总结为以下几点:



  • 清晰的依赖关系

  • 清晰的语法

  • 清晰的语义

  • 偏向组合而不是继承

  • 提供简单的编程模型(垃圾回收、并发)

  • 强大的内置工具(gofmt、godoc、gofix等)


建议有兴趣的同学看看 Go在谷歌:以软件工程为目的的语言设计


Go 语言相对 Python 有哪些优势


这里引用一段知乎上某大牛的回答,如下:




  • 部署简单。Go 编译生成的是一个静态可执行文件,除了 glibc 外没有其他外部依赖。这让部署变得异常方便:目标机器上只需要一个基础的系统和必要的管理、监控工具,完全不需要操心应用所需的各种包、库的依赖关系,大大减轻了维护的负担。这和 Python 有着巨大的区别。由于历史的原因,Python 的部署工具生态相当混乱【比如 setuptools, distutils, pip, buildout 的不同适用场合以及兼容性问题】。官方 PyPI 源又经常出问题,需要搭建私有镜像,而维护这个镜像又要花费不少时间和精力。




  • 并发性好。Goroutine 和 channel 使得编写高并发的服务端软件变得相当容易,很多情况下完全不需要考虑锁机制以及由此带来的各种问题。单个 Go 应用也能有效的利用多个 CPU 核,并行执行的性能好。这和 Python 也是天壤之比。多线程和多进程的服务端程序编写起来并不简单,而且由于全局锁 GIL 的原因,多线程的 Python 程序并不能有效利用多核,只能用多进程的方式部署;如果用标准库里的 multiprocessing 包又会对监控和管理造成不少的挑战【我们用的 supervisor 管理进程,对 fork 支持不好】。部署 Python 应用的时候通常是每个 CPU 核部署一个应用,这会造成不少资源的浪费,比如假设某个 Python 应用启动后需要占用 100MB 内存,而服务器有 32 个 CPU 核,那么留一个核给系统、运行 31 个应用副本就要浪费 3GB 的内存资源。




  • 良好的语言设计。从学术的角度讲 Go 语言其实非常平庸,不支持许多高级的语言特性;但从工程的角度讲,Go 的设计是非常优秀的:规范足够简单灵活,有其他语言基础的程序员都能迅速上手。更重要的是 Go 自带完善的工具链,大大提高了团队协作的一致性。比如 gofmt 自动排版 Go 代码,很大程度上杜绝了不同人写的代码排版风格不一致的问题。把编辑器配置成在编辑存档的时候自动运行 gofmt,这样在编写代码的时候可以随意摆放位置,存档的时候自动变成正确排版的代码。此外还有 gofix, govet 等非常有用的工具。



  • 执行性能好。虽然不如 C 和 Java,但通常比原生 Python 应用还是高一个数量级的,适合编写一些瓶颈业务。内存占用也非常省。


从个人对 Golang 的初步使用来说,体验还是相当不错的,但是也有下面几点需要注意:




  • 驼峰式命名风格(依据首字母大小写来决定其是否能被其他包引用),但我更喜欢 Python 的小写字母加下划线命名风格。




  • 没有好用的包管理器,Golang 官方也没有推荐最佳的包管理方案,目前公认的比较好用的有 Godeps, Govendor 及 Glide,而 Python 的包管理器 pip 已形成自己的一套标准。




  • 多行字符串的变量声明需要用反引号(`),Python 里是三个双引号("""),参考http://stackoverflow.com/questions/7933460/how-do-you-write-multiline-strings-in-go




  • Golang 中的类型匹配是很严格的,不同的类型之间通常需要手动转换,所以在字符串拼接时往往需要对整型进行显式转换,如 fmt.Println("num: " + strconv.Itoa(1))



  • Golang 语言语法里的语法糖并不多,如在 Python 中很流行的 map, reduce, range 等,在 Golang 里都没有得到支持。


另外,推荐阅读 Golang 新手开发者要注意的陷阱和常见错误


学习资料推荐


建议先把 Go 的官方文档过一遍,主要有以下几项:



官方文档看完后,基本也算入门了,这时候可以看看 Go 的示例代码,或者去 Project Euler 刷刷题。


当然也可以去知乎看看大牛们都是如何学习的,链接 https://www.zhihu.com/question/23486344


总结


虽然 Go 有很多被诟病的地方,比如 GC 和对错误的处理方式,但没有任何语言是完美的,从实用角度来讲,Go 有着不输于 Python 的开发效率,完善的第三方工具,以及强大的社区支持,这些就足够了。


相关链接:

https://golang.org/doc/

https://talks.golang.org/2012/splash.article

https://www.zhihu.com/question/21409296

https://www.zhihu.com/question/23486344

http://stackoverflow.com/questions/7933460/how-do-you-write-multiline-strings-in-go

http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/

http://www.oschina.net/translate/go-at-google-language-design-in-the-service-of-software-engineering




本文章为 Cloudinsight 技术团队工程师原创,更多技术文章可访问 Cloudinsight 技术博客Cloudinsight 为可视化系统监控工具,涵盖 Windows、Linux 操作系统,用 Golang 开发的 Cloudinsight Agent 正式开源了,欢迎 fork,Github:https://github.com/cloudinsight/cloudinsight-agent


golang-for-pythonistas 系列持续更新中,欢迎关注~

求一些golang的教程,书籍也可以

有问必答titian 回复了问题 • 31 人关注 • 22 个回复 • 1852 次浏览 • 2016-11-06 14:35 • 来自相关话题

golang有没有好的开源游戏框架

技术讨论lewgun 回复了问题 • 14 人关注 • 8 个回复 • 1680 次浏览 • 2016-10-17 11:23 • 来自相关话题

为什么Go里面大多数的接口返回的是int类型

有问必答negronihe 回复了问题 • 4 人关注 • 3 个回复 • 905 次浏览 • 2016-10-16 13:06 • 来自相关话题

大家推荐哪种golang包管理方式?

有问必答tanran 回复了问题 • 18 人关注 • 15 个回复 • 1630 次浏览 • 2016-10-15 09:19 • 来自相关话题

beego1.8版本功能征集

回复

文章分享mnhkahn 回复了问题 • 17 人关注 • 20 个回复 • 1567 次浏览 • 19 分钟前 • 来自相关话题

println 与 fmt.Println 一起使用为何不是顺序打印?

回复

Golangsongtianyi 回复了问题 • 4 人关注 • 4 个回复 • 174 次浏览 • 23 小时前 • 来自相关话题

使用什么docker image来运行Go程序

回复

有问必答zensh 回复了问题 • 13 人关注 • 13 个回复 • 845 次浏览 • 2 天前 • 来自相关话题

golang 的channel是否适合做消息队列?

回复

有问必答pathbox 回复了问题 • 15 人关注 • 9 个回复 • 1631 次浏览 • 5 天前 • 来自相关话题

go怎么获取本机ip的疑问

回复

有问必答Akagi201 回复了问题 • 6 人关注 • 4 个回复 • 328 次浏览 • 2017-02-09 18:43 • 来自相关话题

请问有golang实现的acc编码/解码库吗?

回复

有问必答Akagi201 回复了问题 • 2 人关注 • 1 个回复 • 136 次浏览 • 2017-02-06 13:54 • 来自相关话题

Go Base64 Decode 的问题

回复

有问必答皇虫 回复了问题 • 4 人关注 • 3 个回复 • 302 次浏览 • 2017-01-29 08:46 • 来自相关话题

go原生的RPC的文档资料,在哪里看啊

回复

有问必答codinghxl 回复了问题 • 6 人关注 • 7 个回复 • 730 次浏览 • 2017-01-21 08:26 • 来自相关话题

如何捕获fatal error

回复

有问必答lrita 回复了问题 • 3 人关注 • 2 个回复 • 245 次浏览 • 2017-01-15 22:21 • 来自相关话题

为什么value receiver可以减少需要回收的垃圾量?

回复

有问必答cholerae 回复了问题 • 5 人关注 • 2 个回复 • 290 次浏览 • 2017-01-12 13:00 • 来自相关话题

Golang CPU pprof 生成的文件无法解析

回复

有问必答astaxie 回复了问题 • 3 人关注 • 2 个回复 • 369 次浏览 • 2016-12-30 11:24 • 来自相关话题

Go能否远程加载一个二进制插件运行?

回复

有问必答stevewang 回复了问题 • 3 人关注 • 1 个回复 • 291 次浏览 • 2016-12-27 13:35 • 来自相关话题

数据库插入的时候怎么使用NULL而不是空字符串

回复

有问必答caibirdme 回复了问题 • 6 人关注 • 5 个回复 • 532 次浏览 • 2016-12-26 13:29 • 来自相关话题

有没有涉及到Golang工作流相关的开源项目?

回复

有问必答Xargin 回复了问题 • 9 人关注 • 3 个回复 • 536 次浏览 • 2016-12-22 01:29 • 来自相关话题

c++如何调用go静态库

回复

有问必答silentred 回复了问题 • 3 人关注 • 2 个回复 • 469 次浏览 • 2016-12-16 18:01 • 来自相关话题

处理文件上传的工具包 - fuh

开源程序lyric 发表了文章 • 0 个评论 • 74 次浏览 • 1 天前 • 来自相关话题

处理文件上传的工具包 - fuh

在平时web开发过程中,总会遇到处理文件上传的场景,每次的处理方式都是以业务为导向进行处理。现在作者就把这一... 查看全部

处理文件上传的工具包 - fuh


在平时web开发过程中,总会遇到处理文件上传的场景,每次的处理方式都是以业务为导向进行处理。现在作者就把这一块单独抽离出来,做成了一个简单的工具包。主要特点是:



  • 支持自定义文件存储

  • 支持自定义文件名

  • 支持自定义文件大小限制


引入简单,方便,欢迎来拍砖!谢谢!


$ go get github.com/LyricTian/fuh

package main

import (
"encoding/json"
"net/http"

"github.com/LyricTian/fuh"
)

func main() {
http.HandleFunc("/fileupload", func(w http.ResponseWriter, r *http.Request) {
finfo, err := fuh.Upload(r, "file", nil, nil)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
json.NewEncoder(w).Encode(finfo)
})

http.ListenAndServe(":8080", nil)
}

dockerSSH用ssh连接到docker

开源程序myml 发表了文章 • 3 个评论 • 91 次浏览 • 2017-02-11 21:59 • 来自相关话题

dockerSSH

用golang.org/x/crypto/ssh 实现的ssh服务器,能直接让你通过ss... 查看全部

dockerSSH


用golang.org/x/crypto/ssh 实现的ssh服务器,能直接让你通过ssh登陆到docker容器内,比如ssh ff756b3ea527@127.0.0.1 会登陆到ID为ff756b3ea527的容器,刚实现的尚不成熟,还有一些功能想去实现,比如scp,sftp

好玩的github项目-用go做个flappy bird

Go开源项目wwdyy 发表了文章 • 1 个评论 • 285 次浏览 • 2017-02-06 22:46 • 来自相关话题

flappy gopher

转自github用户neomede

A flappy bird clone made in go. 查看全部

flappy gopher


转自github用户neomede


A flappy bird clone made in go.


Based on this video and this project by Francesc Campoy, also this project by Sab


Play


Just run "make run" and use any button to jump


github地址:https://github.com/neomede/flappy

golang 特性简介

文章分享sheepbao 发表了文章 • 0 个评论 • 421 次浏览 • 2017-01-22 16:37 • 来自相关话题

golang 特性简介

by sheepbao

主要大概介绍go语言的历史和特性,简单的入门。

来历

很久以前,有一个IT公司,这公司有个传统,允许员工拥有20... 查看全部

golang 特性简介


by sheepbao


主要大概介绍go语言的历史和特性,简单的入门。


来历


很久以前,有一个IT公司,这公司有个传统,允许员工拥有20%自由时间来开发实验性项目。在2007的某一天,公司的几个大牛,正在用c++开发一些比较繁琐但是核心的工作,主要包括庞大的分布式集群,大牛觉得很闹心,后来c++委员会来他们公司演讲,说c++将要添加大概35种新特性。这几个大牛的其中一个人,名为:Rob Pike,听后心中一万个xxx飘过,“c++特性还不够多吗?简化c++应该更有成就感吧”。于是乎,Rob Pike和其他几个大牛讨论了一下,怎么解决这个问题,过了一会,Rob Pike说要不我们自己搞个语言吧,名字叫“go”,非常简短,容易拼写。其他几位大牛就说好啊,然后他们找了块白板,在上面写下希望能有哪些功能(详见文尾)。接下来的时间里,大牛们开心的讨论设计这门语言的特性,经过漫长的岁月,他们决定,以c语言为原型,以及借鉴其他语言的一些特性,来解放程序员,解放自己,然后在2009年,go语言诞生。


思想


Less can be more


大道至简,小而蕴真


让事情变得复杂很容易,让事情变得简单才难


深刻的工程文化


优点



  1. 自带gc。

  2. 静态编译,编译好后,扔服务器直接运行。

  3. 简单的思想,没有继承,多态,类等。

  4. 丰富的库和详细的开发文档。

  5. 语法层支持并发,和拥有同步并发的channel类型,使并发开发变得非常方便。

  6. 简洁的语法,提高开发效率,同时提高代码的阅读性和可维护性。

  7. 超级简单的交叉编译,仅需更改环境变量。(花了我两天时间编译一个imagemagick到arm平台)

  8. 内含完善、全面的软件工程工具。Go语言自带的命令和工具相当地强大。通过它们,我们可以很轻松地完成Go语言程序的获取、编译、测试、安装、运行、运行分析等一系列工作,这几乎涉及了开发和维护一个软件的所有环节。


hello


package main

func main(){
println("hello, sewise")
}

type


主要讲讲特有的类型,其他基本类型不做介绍


slice


切片:可以理解为动态数组,类似c++的vector
声明一个slice


    var slice []T
如:
var ints []int

slice的追加


    ints=append(ints,1)
ints=append(ints,2,3,4,5)

slice的截取


    newInts1:=ints[2:3]
newInts2:=ints[2:]
newInts3:=ints[:4]

map


字典:键值对


    var json map[string]string

interface


接口:方法的集合,是一种合约
栗子:
声明一个bird接口


    var bird interface{
fly()
}

声明一个hen对象(实现bird接口)


    type hen struct {
weight int
hasFeather bool
}

func (h hen)fly(){
fmt.Println("iI can fly")
}

type func (h hen)eat(){
h.weight++
fmt.Println("yes, I can eat")
}

声明一个pig对象(未实现bird接口,因为pig不会fly)


    type pig struct {
age int
weignt int
hasFeather bool
}

func (p pig)run(){
fmt.Println("I can run")
}

func (p pig)eat(){
p.weight += 100
fmt.Println("Yes, I can eat so much")
}

func (p pig)sleep(){
fmt.Println("I slept all my life")
}

// pig can't fly

channel


通道:轻量集队列,传递某种类型的值的通道


    var ch chan int
ch=make(chan int,1)

往ch写入一个数据


    ch<-8888

从ch读取数据


    out:=<-ch

特性:
channel是有长度的,当channel的缓冲为满时,再往里写入就会阻塞,当channel的缓冲为空时,从channel读就会阻塞


package main

import (
"fmt"
"time"
)

func main() {
ch := make(chan int)
fmt.Println("ch len:", len(ch))
go func() {
// 往缓冲满的channel里写数据(阻塞)
// ch <- 1
// 从缓冲为空的channel里读数据(阻塞)
<-ch
fmt.Println("I am in minor goroutine")
}()
fmt.Println("I am in main goroutine")
time.Sleep(2 * time.Second)
}

当长度为0是,就是不带缓冲的channel
长度大于0,就是带缓冲的channel


并发


关键字:go 启动go程
一个普通的函数或方法调用前加上关键字go,即可启动一个goroutine


    go func(){
fmt.Println("start func")
time.Sleep(120*time.Second)
}()

竞争条件检测
-race
race.go


package main

import (
"fmt"
"time"
)

func main() {
a := 1
go func() {
a = 2
}()
a = 3
fmt.Println("a is ", a)

time.Sleep(2 * time.Second)
}

检测:执行go run -race race.go


a is  3
==================
WARNING: DATA RACE
Write at 0x00c420072188 by goroutine 6:
main.main.func1()
/Users/bao/program/go/gowork/hello/src/research/race.go:11 +0x3b

Previous write at 0x00c420072188 by main goroutine:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:13 +0x9f

Goroutine 6 (running) created at:
main.main()
/Users/bao/program/go/gowork/hello/src/research/race.go:12 +0x8e
==================
Found 1 data race(s)

结果分析:
goroutine6运行到第11行和main goroutine运行到13行的时候触发竞争了。而且goroutine6是在第12行的时候产生的。


package


包的管理,关键字importGOPATH


gopath


gopath是一个路径列表,存放go项目工程
GOPATH文件目录结构


├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录

平常项目的目录结构


├── bin  二进制文件目录
├── pkg 编译好的库文件目录
└── src 源码目录
├── main 入口函数目录
└── vendor 当前项目的库目录
└── sheepbao.com
└── glog

import


比如上面的项目,我要在main.go引入glog


package main

// 引入glog包
import "sheepbao.com/glog"

func main(){
glog.Println("test")
}

go的工程工具简介


test


go的命令工具 test,用来做测试


单元测试


go test
只测试函数名被它正确匹配的测试函数
go test -v -run="French|Canal"


栗子:
add.go


package test

func addOne(i int) int {
return i + 1
}

add_test.go


package test

import "testing"

func TestAddOne(t *testing.T) {
result := addOne(1)
if result != 2 {
t.Error("1+1!=2")
}
}

bao@baoMac test$ go test -v .
=== RUN TestAddOne
--- PASS: TestAddOne (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/test 0.006s

基准测试


go test -bench=.
内存的分配情况
go test -bench=FuncName -benchmem
栗子:
stringsCon.go


package bench

import (
"fmt"
)

func Sprintf(s1, s2, s3 string) string {
return fmt.Sprintf("%s%s%s", s1, s2, s3)
}

func AddString(s1, s2, s3 string) string {
return s1 + s2 + s3
}

stringCon_test.go


package bench

import "testing"

var (
s1 = "make it run!"
s2 = "make it right!"
s3 = "make it fast!"
)

func BenchmarkSprintf(b *testing.B) {
for i := 0; i < b.N; i++ {
Sprintf(s1, s2, s3)
}
}

func BenchmarkAddString(b *testing.B) {
for i := 0; i < b.N; i++ {
AddString(s1, s2, s3)
}
}

go test -bench=.


bao@baoMac bench$ go test -bench=.
testing: warning: no tests to run
BenchmarkSprintf-4 5000000 349 ns/op
BenchmarkAddString-4 20000000 61.7 ns/op
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/bench 3.414s

样本测试


package et

import (
"fmt"
)

func ExampleHello() {
fmt.Println("hello, sewise")
// Output: hello, sewise
}

bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- PASS: ExampleHello (0.00s)
PASS
ok _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

如果把上面的// Output: hello, sewise改为// Output: hello, sewis
则样本测试不能通过


bao@baoMac example$ go  test -v .
=== RUN ExampleHello
--- FAIL: ExampleHello (0.00s)
got:
hello, sewise
want:
hello, sewis
FAIL
exit status 1
FAIL _/Users/bao/program/go/gowork/hello/src/research/example 0.006s

pprof


go的命令工具 pprof,用来性能分析(内存使用,泄露和cpu消耗)
go tool pprof



可视化(原是svg文件,下图为截图):


image_1b72f233avto14d7on4h3nlm51g.png-129.8kB



可视化(原是svg文件,下图为截图:


image_1b72euk7b1knr1d1n1ugq2pe19kim.png-176.7kB


go tool pprof --text http://localhost:6060/debug/pprof/heap


go命令教程


资料


http://www.csdn.net/article/2012-07-04/2807113-less-is-exponentially-more


http://www.jianshu.com/p/91e40c3e3acb?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io


http://smallsoho.com/2016/11/20/Go简明教程.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io


大牛真身


最大牌的当属B和C语言设计者、Unix和Plan 9创始人、1983年图灵奖获得者Ken Thompson,这份名单中还包括了Unix核心成员Rob Pike(go语言之父)、java HotSpot虚拟机和js v8引擎的开发者Robert Griesemer、Memcached作者Brad Fitzpatrick,等等。


功能



  • 规范的语法(不需要符号表来解析)

  • 垃圾回收(独有)

  • 无头文件

  • 明确的依赖

  • 无循环依赖

  • 常量只能是数字

  • int和int32是两种类型

  • 字母大小写设置可见性(letter case sets visibility)

  • 任何类型(type)都有方法(不是类型)

  • 没有子类型继承(不是子类)

  • 包级别初始化以及明确的初始化顺序

  • 文件被编译到一个包里

  • 包package-level globals presented in any order

  • 没有数值类型转换(常量起辅助作用)

  • 接口隐式实现(没有“implement”声明)

  • 嵌入(不会提升到超类)

  • 方法按照函数声明(没有特别的位置要求)

  • 方法即函数

  • 接口只有方法(没有数据)

  • 方法通过名字匹配(而非类型)

  • 没有构造函数和析构函数

  • postincrement(如++i)是状态,不是表达式

  • 没有preincrement(i++)和predecrement

  • 赋值不是表达式

  • 明确赋值和函数调用中的计算顺序(没有“sequence point”)

  • 没有指针运算

  • 内存一直以零值初始化

  • 局部变量取值合法

  • 方法中没有“this”

  • 分段的堆栈

  • 没有静态和其它类型的注释

  • 没有模板

  • 内建string、slice和map

  • 数组边界检查

gmcache一个用go写的分布式缓存,类似memcached

开源程序stirlingx 发表了文章 • 0 个评论 • 220 次浏览 • 2017-01-19 16:01 • 来自相关话题

主要是用来练手的,欢迎大家仍砖头

  • 使用ectd做服务发现
  • broker作为代理服务器,对client的请求做转发,用一致性hash算法对key映射到后端gmcache。

项目地... 查看全部

主要是用来练手的,欢迎大家仍砖头



  • 使用ectd做服务发现

  • broker作为代理服务器,对client的请求做转发,用一致性hash算法对key映射到后端gmcache。


项目地址:


https://github.com/liyue201/gmcache


Gmcache


A distributed key/value memory cache written in go.


Features



  • Light weight

  • Pure golang

  • Supports set,get and delete

  • Supports grpc and http protocols

  • Scalable architecture


Architecture


gmcache-cluster

Go 通过 Swig 调用 C/C++ 程序

技术讨论Akagi201 发表了文章 • 1 个评论 • 205 次浏览 • 2017-01-18 21:08 • 来自相关话题

项目地址: https://github.com/Akagi201/swiggo


swiggo


Build Status
Go Report Card
GoDoc


Call C/C++ lib with the help of swig


Generate Go package file and C/C++ wrapper file



  • mv interface.swig/interface.swigxx interface.i

  • For C: swig -go -cgo -intgosize 64 interface.i

  • For C++: swig -go -cgo -c++ -intgosize 64 interface.i


Usage



  • go get github.com/Akagi201/swiggo


TODO



  • [ ] Auto gen Go package files for godoc and IDE to browser Go definitions.

力争做最好的go模板引擎

开源程序Lime 发表了文章 • 3 个评论 • 382 次浏览 • 2017-01-17 13:01 • 来自相关话题

一直觉得 go 没有一个好用的模板引擎,渲染 html 的时候特别痛苦,总有一种有力气却使不出来的感觉。

模板引擎一般有两种实现方式,一种是解析 html 语法树,然后根据一定的规则动态的拼接,另外一种是把模板预先生成代码,渲染模板时调用相... 查看全部

一直觉得 go 没有一个好用的模板引擎,渲染 html 的时候特别痛苦,总有一种有力气却使不出来的感觉。


模板引擎一般有两种实现方式,一种是解析 html 语法树,然后根据一定的规则动态的拼接,另外一种是把模板预先生成代码,渲染模板时调用相关的函数即可。


Go 内置的 template 包使用的是第一种方式,不过很多开源项目使用的是第二种方式,比如 quicktemplate 、 gorazor 等。不过这两个可能由于设计的问题,都没有实现模板继承和模板 include ,而且有的语法个人觉得不是太优雅。


所以我想要一个 go 模板,它具备以下特性:


原生的 golang 语法



  • 支持模板植入代码

  • 支持模板继承和 include

  • 高性能

  • 语法简单、优雅

  • 自动编译


基于以上,实现了 hero 模板引擎,用过 nodejs EJS 模板引擎的童鞋应该很容易上手。 hero 目前已经在 http://bthub.io 线上使用。


Github: https://github.com/shiyanhui/hero


Gophers ,欢迎 issues 和 pr ,让我们一起共同打造 golang 最好的模板引擎!

GopherChina 2017年讲师招募

文章分享astaxie 发表了文章 • 7 个评论 • 362 次浏览 • 2017-01-12 14:24 • 来自相关话题

会议详情: 时间:2017年4月15-16日 地点:上海

GopherChina 是中国的最权威和最实力干货的Go大会,我们致力于为中国广大的Gopher提供最好的大会,我们本着非盈利目的来举办大会,前面两届大会在上海和北京都获得了非常好的... 查看全部

会议详情:
时间:2017年4月15-16日
地点:上海


GopherChina 是中国的最权威和最实力干货的Go大会,我们致力于为中国广大的Gopher提供最好的大会,我们本着非盈利目的来举办大会,前面两届大会在上海和北京都获得了非常好的口碑,今年我们大会将在四月份举办大会。举办Gopher大会,主要是汇集Gopher的广大开发者,聚集一批大规模应用Go的示范企业给大家分享,呈现一场cool的盛会。


这是2015年Go作者之一Robert参会之后写的博客:https://blog.golang.org/gopherchina


第一届我们的大会参会人数是500人,去年在北京差不多达到了1000人的规模, 今年我们组织了1500人的场地,面向的受众也是越来越多,同时我们也邀请了Go team的同学过来分享。


现在开始招募讲师:


https://jinshuju.net/forms/kFEn6i

北京一家具有国际经验的区块链技术企业招聘golang高级软件开发工程师

招聘应聘Nicoli_King 发表了文章 • 3 个评论 • 270 次浏览 • 2017-01-09 00:50 • 来自相关话题

【工作内容】 1、参与区块链平台核心技术开发,包括共识算法、权限控制、P2P等等; 2、参与设计和实现数字资产发行、管理和交易的API等。

【任职资格】 1、精通其一( C / C++ / Java),有丰富而完整的项目开发经验; 2、精通... 查看全部

【工作内容】
1、参与区块链平台核心技术开发,包括共识算法、权限控制、P2P等等;
2、参与设计和实现数字资产发行、管理和交易的API等。


【任职资格】
1、精通其一( C / C++ / Java),有丰富而完整的项目开发经验;
2、精通或擅长 Go 语言;
3、有很好的优化代码和代码层次结构划分能力,有清晰的代码架构思想;
4、统招本科以上学历,6年以上开发经验;
5、能够承担核心代码开发工作;
6、有知名企业或复杂完整项目经历为佳。


【薪资待遇】
1、月薪25-35k;
2、股权期权、五险一金、弹性工作制、午餐、零食、地铁附近。


联系QQ:1423561423

Grumpy:Google开源神器 Go上运行Python

开源程序wwdyy 发表了文章 • 0 个评论 • 380 次浏览 • 2017-01-07 13:46 • 来自相关话题

Grumpy是一个Python to Go的源码源代码翻译编译器和运行时,旨在取代CPython 2.7。

关键区别在于,Grumpy是将Python源码编译为Go源代码,然后将其编译为本地代码,而不是字节码。这也就意味着Grumpy没... 查看全部

Grumpy是一个Python to Go的源码源代码翻译编译器和运行时,旨在取代CPython 2.7。


关键区别在于,Grumpy是将Python源码编译为Go源代码,然后将其编译为本地代码,而不是字节码。这也就意味着Grumpy没有虚拟机(VM)。编译好的Go源码是对Grumpy运行时的一系列调用,一个Go库服务于具有相似目的的Python C API(尽管不直接支持C API)。


运行Grumpy程序


方法1:grumprun:


执行Grumpy程序的最简单方法就是使用make run,它封装了一个名为grumprun的shell脚本,它将stdin上的Python代码基于Grumpy构建和运行。以下所有的命令都假设从Grumpy源码根目录开始运行:


echo "print 'hello, world'" | make run

方法2:grumpc


对于复杂一些的程序,你需要使用grumpc把Python代码编译成Go源码以后再进行构建。首先,写一个简单的.py脚本;


echo 'print "hello, world"' > hello.py

接下来,创建工具链并导出一些使工具链工作的环境变量:


 make

export GOPATH=$PWD/build

export PYTHONPATH=$PWD/build/lib/python2.7/site-packages

最后,编译Python脚本并从中构建一个二进制文件:


tools/grumpc hello.py > hello.go

go build -o hello hello.go

好了,现在执行./hello二进制到你的核心内容里即可。


关于Grumpy更多内容,大家可以访问其源码托管地址:https://github.com/google/grumpy

原来结构体函数还能这样用

文章分享myml 发表了文章 • 8 个评论 • 310 次浏览 • 2017-01-06 11:04 • 来自相关话题

平常使用结构体函数是这么用

type A struct {
}

func (a *A) Print() {
    fmt.... 			查看全部
					

平常使用结构体函数是这么用


type A struct {
}

func (a *A) Print() {
fmt.Println("this is A")
}

func main() {
a := A{}
a.Print()
}

恩,没啥问题,然后还可以这样用


type A struct {
}

func (a A) Print() {
fmt.Println("this is A")
}
func (a *A) Print2() {
fmt.Println("this is A")
}

func main() {
a := A{}
A.Print(a)
(*A).Print2(&a)
}

结合接口的话就可以这样


type I interface {
Print()
}
type A struct {
}

func (a *A) Print() {
fmt.Println("this is A")
}

type B struct {
}

func (b *B) Print() {
fmt.Println("this is B")
}

func main() {
a := A{}
b := B{}
I.Print(&a)
I.Print(&b)
}

数人云Mesos调度器Swan v0.2最新功能演示

开源程序数人云 发表了文章 • 0 个评论 • 183 次浏览 • 2016-12-29 11:00 • 来自相关话题

数人云Mesos调度器Swan开源已经一个月啦,在社区和大家的共同呵护下成长了许多。小数带来了Swan v0.2的新版本,添加了很多新功能,工程师为了... 查看全部

数人云Mesos调度器Swan开源已经一个月啦,在社区和大家的共同呵护下成长了许多。小数带来了Swan v0.2的新版本,添加了很多新功能,工程师为了大家更好地了解Swan的新功能,为大家提供了录屏,欢迎收看!


腾讯地址:
https://v.qq.com/x/page/p0358dzspz5.html


Fork me on GitHub!
https://github.com/Dataman-Cloud/swan


关于数人云Mesos调度器Swan


Swan是基于Mesos Restful API编写的应用调度框架,可以帮助用户轻松发布应用,实现应用的滚动更新,并根据用户指定的策略做应用的健康检测和故障转移。

通过 github.com/jung-kurt/gofpdf 包实现自定义字体库的添加及PDF的生成

文章分享xieyanke 发表了文章 • 1 个评论 • 227 次浏览 • 2016-12-22 23:05 • 来自相关话题

为朋友做个demo,顺便分享一下:

github.com/jung-kurt/gofpdf 是一个用于生成PDF的包

包的安装及自定义字库添加工具的安装

  1. go get github.com/jun... 查看全部

为朋友做个demo,顺便分享一下:


github.com/jung-kurt/gofpdf 是一个用于生成PDF的包


包的安装及自定义字库添加工具的安装



  1. go get github.com/jung-kurt/gofpdf

  2. go install github.com/jung-kurt/gofpdf/makefont


通过 makefont 工具生成自定义字体库



  1. makefont -dst=fonts -embed -enc=/Users/xieyanke/GOPATH/src/github.com/jung-kurt/gofpdf/font/cp1252.map /Library/Fonts/Chalkduster.ttf


这里 makefont -dst 指定了相对路径 fonts 这个目录作为字库生成的目录,后面代码中加载字库需要引用这个路径


package main

import (
"log"

"github.com/jung-kurt/gofpdf"
)

func main() {
// 这里./fonts 是指定了makefont 工具生成自定义字体库的目录
pdf := gofpdf.New("P", "mm", "A4", "./fonts")
// 加载定义的字库
pdf.AddFont("cld", "", "Chalkduster.json")
pdf.AddPage()
pdf.SetFont("cld", "", 22)
pdf.Cell(40, 10, "A new pdf")

err := pdf.OutputFileAndClose("demo.pdf")

if err != nil {
log.Println(err)
}
}
// go run example.go,查看当前目录下 pdf 进行验证

解读2016之Golang篇:极速提升,逐步成熟

文章分享wwdyy 发表了文章 • 9 个评论 • 710 次浏览 • 2016-12-17 14:39 • 来自相关话题

Go语言已经7岁了!今年8月,Go 1.7如期发布。撰写本稿时,Go 1.8的测试版也出来了。我们正在热切盼望着明年2月的Go 1.8正式版。

如果你关注 TIOBE的编程语言排行榜 就会发现,截止到2016年11月,Go语言从原先的第50... 查看全部

Go语言已经7岁了!今年8月,Go 1.7如期发布。撰写本稿时,Go 1.8的测试版也出来了。我们正在热切盼望着明年2月的Go 1.8正式版。


如果你关注 TIOBE的编程语言排行榜 就会发现,截止到2016年11月,Go语言从原先的第50多位经过多次上窜已经跃到了第13位,跻入绝对主流的编程语言的行列!这份排行榜每月都会更新,并基于互联网上的程序员老鸟、教学课程和相关厂商的数量进行排名。在国内,从我这几年运营Go语言北京用户组的经历来看,可以明显地感觉到Go语言的在国内的大热。N多初创互联网企业都选用Go语言作为他们的基础技术栈。我还发现,已经有在大数据、机器人等尖端科技领域耕耘的国内公司开始使用Go语言。这门语言现在已经是无孔不入了。


1. 回顾


遥想去年的1.5版本,Go运行时系统和标准库刚完成去C化,转而完全由Go语言和汇编语言重写。到现在,Go的源码已有了较大的改进,Go语言版本的Go语言也更加成熟了。我下面就带领大家一起回顾一下Go语言在2016年做出的那些大动作。


1.1 极速GC


当然,首先要说的还是性能。Go语言本身最大的性能提升依然在GC(garbage collection,垃圾回收)方面。从Go 1.5时标榜的GC耗时百毫秒级,到今天的全并发GC使得耗时达到毫秒级,再到即将发布的Go 1.8由于实施了诸多改进而达成的百微秒级以下的GC耗时,真可谓是突飞猛进!


图1 GC停顿时间——Go 1.5 vs. Go 1.6



图2 GC停顿时间——Go 1.7


在经历了如此变化之后,如果你现在再说你的Go程序的性能瓶颈在GC上,那只能让人侧目了。


当然,Go语言对自身性能的提升远不止于此。


1.2 对HTTP/2的支持


很早以前,Go语言团队就开始跟进HTTP/2草案了。从Go 1.6开始,我们其实已经可以间接地在Go程序中使用到HTTP/2了,应用场景如:使用Go程序开发基于HTTPS协议的服务端和客户端。不过,这一切都是自动适配的,Go官方并未暴露出可以指定或配置HTTP/2模块的任何API。另外,在还未发布的Go 1.8中,HTTP/2还会得到更广泛的支持。


1.3 httptrace包


Go 1.7的标准库中新增了net/http/httptrace代码包(https://godoc.org/net/http/httptrace)。
它提供了一种调试HTTP请求和响应的方式。你可以像下面这样轻易地获取基于HTTP协议的通讯过程的详细信息。


package main

import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptrace"
"os"
)

func main() {
traceCtx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
GetConn: func(hostPort string) {
fmt.Printf("Prepare to get a connection for %s.\n", hostPort)
},
GotConn: func(info httptrace.GotConnInfo) {
fmt.Printf("Got a connection: reused: %v, from the idle pool: %v.\n",
info.Reused, info.WasIdle)
},
PutIdleConn: func(err error) {
if err == nil {
fmt.Println("Put a connection to the idle pool: ok.")
} else {
fmt.Println("Put a connection to the idle pool:", err.Error())
}
},
ConnectStart: func(network, addr string) {
fmt.Printf("Dialing... (%s:%s).\n", network, addr)
},
ConnectDone: func(network, addr string, err error) {
if err == nil {
fmt.Printf("Dial is done. (%s:%s)\n", network, addr)
} else {
fmt.Printf("Dial is done with error: %s. (%s:%s)\n", err, network, addr)
}
},
WroteRequest: func(info httptrace.WroteRequestInfo) {
if info.Err == nil {
fmt.Println("Wrote a request: ok.")
} else {
fmt.Println("Wrote a request:", info.Err.Error())
}
},
GotFirstResponseByte: func() {
fmt.Println("Got the first response byte.")
},
})
req, err := http.NewRequest("GET", "http://www.golang.org/", nil)
if err != nil {
log.Fatal("Fatal error:", err)
}
req = req.WithContext(traceCtx)
_, err = http.DefaultClient.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "Request error: %v\n", err)
os.Exit(1)
}
}

强烈建议你动手运行一下这个小程序,享受一下掌控全局的感觉。


1.4 子测试


Go 1.7中增加了对子测试(https://blog.golang.org/subtests
的支持,包括功能测试和性能测试。子测试的主要目的是在测试函数中区分和展示因不同的测试参数或测试数据带来的不同的测试结果。请看下面的测试程序。


package subtest

import (
"fmt"
"math/rand"
"strconv"
"testing"
)

// KE 代表键-元素对。
type KE struct {
key string
element int
}

// BenchmarkMapPut 用于对字典的添加和修改操作进行测试。
func BenchmarkMapPut(b *testing.B) {
max := 5
var kes []KE
for i := 0; i <= max; i++ {
kes = append(kes, KE{strconv.Itoa(i), rand.Intn(1000000)})
}
m := make(map[string]int)
b.ResetTimer()
for _, ke := range kes {
k, e := ke.key, ke.element
b.Run(fmt.Sprintf("Key: %s, Element: %#v", k, e), func(b *testing.B) {
for i := 0; i < b.N; i++ {
m[k] = e + i
}
})
}
}

在程序所在目录下使用go test -run=^$ -bench .命令运行它之后就会看到,针对每一个子测试,go test命令都会打印出一行测试摘要。它们是分离的、独立统计的。这可以让我们进行更加精细的测试,细到每次输入输出。上述打印内容类似:
BenchmarkMapPut/Key:_0425,_Element:_498081-4 30000000 40.6 ns/op
BenchmarkMapPut/Key:_1540,_Element:_727887-4 30000000 41.7 ns/op
BenchmarkMapPut/Key:_2456,_Element:_131847-4 30000000 43.3 ns/op
BenchmarkMapPut/Key:_3300,_Element:_984059-4 30000000 46.1 ns/op
BenchmarkMapPut/Key:_4694,_Element:_902081-4 30000000 48.4 ns/op
BenchmarkMapPut/Key:_5511,_Element:_941318-4 30000000 59.3 ns/op
PASS


ok _/Users/haolin/infoq-2016_review_go /demo/subtest 8.678s


1.5 vendor目录


在Go 1.5的时候,官方启用了一个新的环境变量——GO15VENDOREXPERIMENT。该环境变量可以启动Go的vendor目录
https://golang.org/s/go15vendor
并用于存放当前代码包依赖的代码包。在Go 1.5中,若GO15VENDOREXPERIMENT的值为1则会启动vendor目录。Go 1.6正相反,默认支持vendor目录,当GO15VENDOREXPERIMENT的值为0时禁用vendor目录。到了Go 1.7,官方完全去掉了这个环境变量。这也代表着对vendor目录的正式支持。Go语言的实验特性一般都是按照类似的路数一步步迈向正式版的。


1.6 其他值得一提的改进


1.6.1 检测并报告对字典的非并发安全访问


从Go 1.6开始,Go运行时系统对字典的非并发安全访问采取零容忍的态度。请看下面的程序。


package main

import "sync"

func main() {
const workers = 100
var wg sync.WaitGroup
wg.Add(workers)
m := map[int]int{}
for i := 1; i <= workers; i++ {
go func(i int) {
for j := 0; j < i; j++ {
m[i]++
}
wg.Done()
}(i)
}
wg.Wait()
}

该程序在未施加任何保护的情况下在多个Goroutine中并发地访问了字典实例m。我们知道,Go原生的字典类型是非并发安全的。所以上面这样做很可能会让m的值产生不可预期的变化。这在并发程序中应该坚决避免。在1.6之前,如此操作的Go程序并不会因此崩溃。但是在1.6,运行上述程序后就立刻会得到程序崩溃的结果。Go运行时系统只要检测到类似代码,就会强制结束程序并报告错误。


1.6.2 sort包的性能提升


Go语言团队一直致力于标准库中众多API的性能提升,并且效果向来显著。我把sort包单拎出来强调是因为sort.Sort函数因性能优化而在行为上稍有调整。在Go 1.6,sort.Sort函数减少了大约10%的比较操作和交换操作的次数,从而获得了20%~50%的性能提升。不过,这里有一个副作用,那就是sort.Sort函数的执行会使排序算法不稳定。所谓不稳定的排序算法,就是排序可能会使排序因子相等的多个元素在顺序上不确定。比如,有如下需要根据长度排序的字符串的切片:


var langs= []string{"golang", "erlang", "java", "python", "php", "c++", "perl"}

经sort.Sort函数排序后,该切片只几个长度相等的元素golang、erlang和python的先后顺序可能就不是这样了,可能会变成erlang、golang、python。虽然它依然会依据排序因子(这里是字符串长度)进行完全正确的排序,但是如此确实可能对一些程序造成影响。


如果你需要稳定的排序,可以使用sort.Stable函数取而代之。


1.6.3 context包进入标准库


在Go 1.7发布时,标准库中已经出现了一个名为context的代码包。该代码包原先的导入路径为golang.org/x/context,而后者现在已经不存在了。context包被正式引入标准库,并且标准库中的很多API都因此而做了改变。context.Context类型的值可以协调多个Groutine中的代码执行“取消”操作,并且可以存储键值对。最重要的是它是并发安全的。与它协作的API都可以由外部控制执行“取消”操作,比如:取消一个HTTP请求的执行。


1.6.4 go tool trace的增强


go tool trace自Go 1.5正式加入以来,成为了Go程序调试的又一利器。到了Go 1.7,它已经得到了大幅增强。比如,执行时间的缩短、跟踪信息的丰富,等等。


1.6.5 unicode包现基于Unicode 9.0


Go 1.7升级了unicode包,使它支持Unicode 9.0标准。在这之前,它支持的Unicode 8.0标准。


1.6.6 新的编译器后端——SSA


SSA 作为新的编译器后端,可以让编译器生成压缩比和执行效率都更高的代码,并为今后的进一步优化提供了更有力的支持。在性能方面,它可以让程序减少5%至35%的CPU使用时间。


到这里,我向大家展示了Go语言在2016年的一些显著变化。由于篇幅原因,还有很多Go运行时系统和标准库的改动没能提及。尤其是性能方面的改进一直在持续,并潜移默化地为广大Go程序员提供着底层红利。


我强烈建议所有Go程序员紧跟Go语言团队的脚步,升级版本,享受红利。


2. 展望


2.1 新版本


关于展望,莫过于广大Go程序员翘首期盼的Go 1.8了。这里提一下几个如甘霖般的特性。


Go编写的HTTP服务器支持平滑地关闭。这一功能早已由很多第三方代码包实现,但是这次官方终于给出了答案。
支持HTTP/2的Server Push。这个就不多说了,肯定会比Hijack更好用。
新增了plugin包,你可以把一些Go程序作为插件动态地加载进你的程序了。
更广泛的上下文支持,自从标准库中有了context包,它就在很多地方起作用了。很多基于标准库的接口功能都可以执行“取消”操作。在Go 1.8中,范围将进一步扩大,比如:database/sql包和testing包都对上下文进行了支持。
sort包的功能改进,对于切片,我们不用再为了使用它的排序功能去编写某个接口的实现类型。
go test命令有了新的标记:-mutexprofile。该标记用于提供关于锁争用的概要文件。
当然,最值得期待的仍然是Go在性能上的提升,尤其是GC方面,又要有一次飞跃了!另外,defer语句的执行会比之前快整整两倍!cgo的调用开销也降低了将近一半!


2.2技术社区


其实,除了对Go语言本身的展望,我们也应该憧憬Go社区(尤其是国内Go社区)的发展。中国现在已经差不多是Go程序员最多的国家了。如果打开Github上Go语言的Wiki(https://github.com/golang/go/wiki/GoUsers
你就会发现,那里已经有一个非常长的列表了。其中的公司达到了近200家,相比于2015年年底翻了将近三倍。而且我相信这只是一小部分,只是在Github上有自己的官方组织且对社区有贡献的一部分公司。不过,你可能还会发现,在China那一栏下的公司却只有一家。这是为什么呢?比较值得深思。我想这也许能从侧面反映出对国际技术社区(尤其是开源社区)有贡献的国内公司太少的问题。在2016年12月初举办的一个大型开源技术盛典的讲台上,某开源公司CEO提到了程序员对开源社区应该不只索取更要奉献,这样才能更好地宣传和推销自己。同时,组织机构也不应该成为大家合作的瓶颈。但是,我想国内的实际情况却恰恰相反。我们国内的计算机技术公司,甚至技术驱动的互联网公司,大都没有为开源社区做奉献的习惯,甚至从规章制度上就是明令禁止的。从这方面看,我觉得那个列表中的China栏的惨状也着实不冤。我热切盼望到了明年这个China栏能够变长很多。


不过,从Github以及国内一些代码托管仓库上的Go项目数量上看,国人编写的Go软件其实已经非常多了。近年来崛起的国内Go开源项目已有不少,特别是(按Star数排列)Gogs、Beego、TiDB、Codis、Pholcus、Hprose、Cyclone等等。他们都已经在国际或国内有了一定的影响力。另外,国人或华人参与的国际Go开源项目更是众多,比如很多人熟知的容器技术领域翘楚Docker、Kubernates、Etcd,等等。


当然,除了一些拔尖的人和拔尖的项目。大多数中国Go程序员和爱好者还是只在国内活跃的。国内的很多地方都自行发起了Go语言用户组,包括但不限于:北京、上海、深圳、杭州,大连、香港等。在各个地方举办的Go语言技术聚会也更加专业、更加频繁,同时规模更大。仅在北京,2016年参加此类聚会或活动的人次就将近400,Go语言北京用户组的微信公众号(golang-beijing)的粉丝数也超过了2000。据悉,在2017年,各地的Go语言用户组还会有更大的动作。


我个人认为,如今Go语言的国内推广已经基本完成了科普阶段,现在我们可以实行更加轻松的推波助澜、顺水推舟的推广策略了。由于Go语言的优秀以及不断的进化,现在自发地关注Go语言的人越来越多了,尤其是在高等学府和编程新手的人群中。


Go语言很好学,配套工具完善,开发和运行效率高,应用领域众多,国内社区也很活跃,有各种各样的中文资料和教程,进阶并不难,其工程化理念也相当得民心。如果你不是一点时间都没有的话,我建议你学一学这门简约、高效的编程语言。在互联网时代,尤其是是移动互联网时代,它已经大有作为。即使对于炙手可热的大数据、微服务等新型领域和理念而言,它也是一个相当重要的技术栈。甚至在即将爆发的人工智能和机器人大潮,我相信,Go语言也必会大放异彩!


作者介绍


郝林,Go语言北京用户组的发起人,极客学院Go语言课程顾问,著有图灵原创图书《Go并发编程实战》,同时也是在线免费教程《Go命令教程》和《Go语言第一课》的作者。目前在微赛时代任平台技术负责人。


参考文献


Go 1.6 Release Notes: https://tip.golang.org/doc/go1.6


Go 1.7 Release Notes: https://tip.golang.org/doc/go1.7


Go 1.8 Release Notes(Beta): https://tip.golang.org/doc/go1.8


The State of Go(2016): https://talks.golang.org/2016/state-of-go.slide


来自:http://www.infoq.com/cn/articles/2016-review-go