beego1.8版本功能征集

mnhkahn 回复了问题 • 17 人关注 • 20 个回复 • 1568 次浏览 • 32 分钟前 • 来自相关话题

Go 1.8新功能声明(英文ppt版)

soul008 发表了文章 • 0 个评论 • 198 次浏览 • 3 天前 • 来自相关话题

Go 1.8新功能

这里写图片描述 ... 			<a class=查看全部

Go 1.8新功能


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

golang实时消息平台NSQ的使用

changjixiong 发表了文章 • 6 个评论 • 283 次浏览 • 2017-02-13 19:55 • 来自相关话题

NSQ是什么

(本文作者 changjixiong,以下是正文)

NSQ是一个实时消息平台,引用一段InfoQ上的介绍:

“NSQ是一... 			查看全部
					

NSQ是什么


(本文作者 changjixiong,以下是正文)


NSQ是一个实时消息平台,引用一段InfoQ上的介绍:


“NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,代码托管在GitHub。NSQ可用于大规模系统中的实时消息服务,并且每天能够处理数亿级别的消息,其设计目标是为在分布式环境下运行的去中心化服务提供一个强大的基础架构。NSQ具有分布式、去中心化的拓扑结构,该结构具有无单点故障、故障容错、高可用性以及能够保证消息的可靠传递的特征。NSQ非常容易配置和部署,且具有最大的灵活性,支持众多消息协议。”

如何开始使用


这里有一个例子用来说明如何安装、启动以及发送与接收消息:
An Example of Using NSQ From Go(地址:http://tleyden.github.io/blog/2014/11/12/an-example-of-using-nsq-from-go/)


构建消息的响应函数


如果单是用一个匿名函数来处理收到的消息显然是不够的,下面用代码来演示一下如果根据收到的消息来使用相应的处理函数。


生产者


首先我们来创建生产者


config := nsq.NewConfig()
w, _ := nsq.NewProducer("127.0.0.1:4150", config)

jsonData := []string{}
jsonData = append(jsonData, `
{
"func_name":"BarFuncAdd",
"params":[0.5,0.51]
}`)
jsonData = append(jsonData, `
{
"func_name":"FooFuncSwap",
"params":["a","b"]
}`)

for _, j := range jsonData {
w.Publish("Topic_json", []byte(j))
}

上面的代码向NSQ发送了2个json格式的消息,从字面上不难看出其目的是调用2个函数,分别是BarFuncAdd和FooFuncSwap。


消费者


现在我们来创建消费者


config := nsq.NewConfig()
config.DefaultRequeueDelay = 0
config.MaxBackoffDuration = 20 * time.Millisecond
config.LookupdPollInterval = 1000 * time.Millisecond
config.RDYRedistributeInterval = 1000 * time.Millisecond
config.MaxInFlight = 2500

MakeConsumer("Topic_json", "ch", config, HandleJsonMessage)

MakeConsumer的定义如下:


func MakeConsumer(topic, channel string, config *nsq.Config,
handle func(message *nsq.Message) error) {
consumer, _ := nsq.NewConsumer(topic, channel, config)
consumer.AddHandler(nsq.HandlerFunc(handle))
err := consumer.ConnectToNSQD("127.0.0.1:4150")
if err != nil {
log.Panic("Could not connect")
}
}

处理器函数


NSQ消息的处理器函数定义如下:


func HandleJsonMessage(message *nsq.Message) error {

resultJson := reflectinvoke.InvokeByJson([]byte(message.Body))
result := reflectinvoke.Response{}
err := json.Unmarshal(resultJson, &result)
if err != nil {
return err
}
info := "HandleJsonMessage get a result\n"
info += "raw:\n" + string(resultJson) + "\n"
info += "function: " + result.FuncName + " \n"
info += fmt.Sprintf("result: %v\n", result.Data)
info += fmt.Sprintf("error: %d,%s\n\n", result.ErrorCode,
reflectinvoke.ErrorMsg(result.ErrorCode))

fmt.Println(info)

return nil
}

功能函数


处理器函数根据收到的json数据通过反射最终调用了Foo的FooFuncSwap方法及Bar的BarFuncAdd方法。


type Foo struct {
}

type Bar struct {
}

func (b *Bar) BarFuncAdd(argOne, argTwo float64) float64 {

return argOne + argTwo
}

func (f *Foo) FooFuncSwap(argOne, argTwo string) (string, string) {

return argTwo, argOne
}

怎么调用的


reflectinvoke.InvokeByJson是如何根据形如:


{
"func_name":"BarFuncAdd",
"params":[0.5,0.51]
}

的 json数据调用Bar.BarFuncAdd的?
请参考《golang通过反射使用json字符串调用struct的指定方法及返回json结果》(如果前面这段没有连接地址,那肯定是文章被爬虫干掉了连接,请找本文的原文阅读)


文中代码的完整内容在https://github.com/changjixiong/goNotes/tree/master/nsqNotes以及https://github.com/changjixiong/goNotes/tree/master/reflectinvoke中。


注意事项


同一个消息channel如果有多个消费者则消费者收到的消息是不确定的。例如,如果将文中的生产者运行一个实例,将消费者运行两个实例(命名为A,B),则会出现A收到2个消息或者B收到2个消息或者AB各收到一个消息。

第三届GopherChina大会正式启动了

junnplus 回复了问题 • 12 人关注 • 10 个回复 • 855 次浏览 • 2017-02-12 10:54 • 来自相关话题

疑似刷论坛做硬推广

lgn21st 回复了问题 • 3 人关注 • 3 个回复 • 208 次浏览 • 2017-02-10 13:55 • 来自相关话题

简单,好玩,有趣的命令行版12306(golang)

aliasliyu4 发表了文章 • 0 个评论 • 273 次浏览 • 2017-02-06 14:26 • 来自相关话题

前言

17年的春节即将临近的时候,跟大多数人一样都需要抢一下回家的票,庆幸我买到了回家的票,因为目的地离家还有一段距离,所以需要知道到达的时间,然后安排下中转回家的行程。就想到如果再terminal中直接可以查就好了,接着就是googl... 查看全部

前言


17年的春节即将临近的时候,跟大多数人一样都需要抢一下回家的票,庆幸我买到了回家的票,因为目的地离家还有一段距离,所以需要知道到达的时间,然后安排下中转回家的行程。就想到如果再terminal中直接可以查就好了,接着就是google了一下,果然网上有很多类似的东西,但是查询火车时刻表的功能好像没有,那就自己写吧。


环境



  1. chrome

  2. mac


项目地址


https://github.com/JingDa-open-source-community/go-home


旅途


从12306官网开始


查找火车时刻表api


登陆12306输入出发地和目的地,会出来很多车子,然后选择你已经买到的那趟。见下图。

打开调试工具command+shift+j),查看网络,可以看到请求的url,点击这个url可以看到返回一个json,包含了这趟车的时刻信息和其他的一些状态信息


时刻表url--》https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=5l000G138920&from_station_telecode=AOH&to_station_telecode=NXG&depart_date=2017-01-25,可以看到中间有train_no车次编号from_station_telecode出发站(代号) to_station_telecode到达站(代号) depart_date出发日期,重点看一下车次编号是一个经过了处理的数据,这趟车是G1389后面还带了两个数,出发城市和到达城市也是一个映射关系。google一下发现城市的映射关系保存在https://kyfw.12306.cn/otn/reso ... .8968,这样我们通过一些简单的处理就能得到城市和相对应的代码,很容易想到把他们放在一个map里面是再好不过的。
下面是完整的处理:


 func Stations(stationTetx []byte) map[string]string {
comp, _ := regexp.Compile("([\u4e00-\u9fa5]+)\\|([A-Z]+)")

datas := comp.FindAll(stationTetx, -1)

cityMap2Code := make(map[string]string, len(datas))
for _, v := range datas {
temp := strings.Split(string(v), "|")
cityMap2Code[temp[0]] = temp[1]
}
return cityMap2Code
}

还有一个问题就是车次编号的代码是如何生成的,好在他们也是可以通过url访问到的。
https://kyfw.12306.cn/otn/resources/js/query/train_list.js?scriptVersion=1.5462
这个文件稍微有些大,我们经过一次处理保存在了本地(最好的方式是保存的mysql中,但是鉴于这是一个简单的项目就没有这样做),大概的形式是:


{
"2017-01-03": {
"1095": {
"Train_no": "270000109500",
"From": "太原",
"To": "兰州西"
}
// 省略很多
}

可以看到这个结构包含一趟车的时间,车次,车次编号,出发地和终点。


渲染数据


terminal中显示表格的包有很多,我用了github上的tablewriter,他的使用是很简单。你也可以加一些自己的序列化控制符,事实上我也是这样干的。


查询火车时刻表



查询火车余票



更新本地数据



新增了对window console的color支持,同时支持cygwin和mysys
如果有同学愿意和我一起做这个事情,随时都欢迎!

2017年 GopherChina 大会期望在哪里召开?

appleboy 回复了问题 • 19 人关注 • 21 个回复 • 955 次浏览 • 2017-02-04 19:49 • 来自相关话题

glide get包 版本问题

astaxie 回复了问题 • 2 人关注 • 1 个回复 • 202 次浏览 • 2017-01-26 21:51 • 来自相关话题

GopherChina预祝大家新年快乐

astaxie 发表了文章 • 1 个评论 • 167 次浏览 • 2017-01-25 18:44 • 来自相关话题

GopherChina自建立以来,得到了大家的很多支持,这里祝大家新的一年里面心想事成,开心生活

查看全部

GopherChina自建立以来,得到了大家的很多支持,这里祝大家新的一年里面心想事成,开心生活


從商業利益看 Go 程式語言

appleboy 发表了文章 • 0 个评论 • 370 次浏览 • 2017-01-24 16:07 • 来自相关话题

文章轉錄自: 從商業利益看 Go 程式語言

從 2016 年開始寫 查看全部

文章轉錄自: 從商業利益看 Go 程式語言


從 2016 年開始寫 Go 程式語言,在這一年我向很多朋友介紹了 Go 語言,很多人就不經問到為什麼我這麼喜歡 Go 語言,在公司內同事或主管更會問,為什麼要從 Node.js 或其他語言轉換到 Go,Go 語言有什麼地方可以帶給公司更大的利益,否則為什麼要多花時間跟人力去嘗試 Go 語言。如果團隊要建置一個商業 Web 服務,那我覺得底下的優點,是讓您選擇 Go 語言的最主要原因。


Go 優勢



  • 快速又簡單部署

  • 支援跨平台編譯

  • 保護原始程式碼

  • 善用多核心處理


底下會針對上述提到的優點進行詳細說明。


1. 快速部署


傳統部署


大家都知道 Golang 可以將專案程式碼編譯成一個二進制檔案,直接部署此檔案會比上傳上百的或上千個檔案還要來得容易。傳統上傳多個檔案是非常慢的,這就是為什麼我們在部署之前會將所有檔案透過 zip 或 tar 的方式打包成一個檔案再部署到機器上,除此之外,上傳後,伺服器端要另外解壓縮或者做其他事情,想想看要寫多少 Shell Script 才能完成此事情,而這些事情都是要靠 DevOps 工程師去撰寫,以及花時間去調整 CI 伺服器 (像是 Jenkins)。


伺服器設定


當然還沒完,檔案上傳完後,每一台伺服器都需要準備相關軟體及設定,這時候可以透過 DockerPuppetChef 完成這些事情,這些都是要花很大量的時間去處理,另外還要處理相對應安全性問題,像是 PHPPythonRuby 甚至 Node.js 版本的升級,太多層面需要考量。


用 Go 語言


在 Go 語言,你只需要將程式碼編譯出二進制執行檔,就可以直接丟到多台伺服器,直接啟動,並不需要準備各種環境或軟體設定,省下來的時間就是大量的金錢。如果是用 Go 語言,我相信團隊內的 DevOps 工程師會很感謝你。假如團隊還沒將 DevOps 流程納入公司的商業考量,那您就落伍了。一位好的 DevOps 工程師可以幫團隊省下很多資金。


2. 不需要 Web 伺服器


這點其實就跟 Node.js 很像,你不需要 Apache 或 Tomcat 或 Nginx 等相關服務,Go 的執行檔就可以處理 Http 連線,這意味著不會有伺服器設定,也不需要維護成本,更不用考慮伺服器安全性問題。當然你執意要使用 load balance 像是 NginxHAProxy 這時候就會變得比較難除錯,也會多花不少時間再調整設定。


3. 保護程式碼


這點非常重要,如果你是賣軟體或者是雲端的公司,這時候客戶希望你將整套雲端放置在客戶公司內部,讓他們測試使用,這時候如果你是使用 Node.js, Ruby 或 PHP 的話,你只能乖乖的將整套原始碼放置在對方公司,並且心驚膽跳的怕對方有意去複製整套程式碼,這時候你敢跟老闆講說,我們需要將程式碼放到對方公司嗎?但是如果是在 Go,我們只需要給客戶一個檔案,請他們直接執行,就可以將服務跑起來,如果想要 decompile 此 binary,答案是 NO。


4. 多核心處理


Go 是個多核心處理的程式語言,這對於伺服器非常重要,許多 web 多語言都是跑 single thread,所以會閒置許多系統效能,現在的伺服器幾乎都是多核 CPU 了,像在 Node.js 你就必須在一台機器跑多個 Node 服務,才可以有效率地發揮效能。在 Go 1.5 版本後 (含 1.5) 已經將 GOMAXPROCS 預設值為系統可用的多核數,所以只要啟動一個執行檔,就可以將系統效能發揮到極限。


5. 跨平台編譯


Go 語言可以將程式碼編譯成 WindowsMacOSLinux 的執行檔,方便攜帶或測試,想看看業務到外面跟客戶 Demo,還要連到 Internet 才可以 Demo 給客戶看,如果網路環境不好或者是沒網路該怎麼辦呢?這時候你只需要攜帶一個執行檔在身上就可以解決您的問題。在團隊內部,每次 QA 都要等工程師部署到內部機器才可以開始測試,這時只要給他們執行檔,就不需要等待工程師部署才可以測試,省下多少時間,這些寶貴的時間都是金錢啊。


結論


其實你會發現上面提到的所有優勢都是省下時間金錢,時間在公司是非常重要及寶貴,大家可以想看看,省下的時間是不是可以讓團隊多做一些事情,讓公司更進步更有競爭力呢?

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

  • 数组边界检查

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读取java或者go的webservice服务

小蚂蚁 发表了文章 • 0 个评论 • 156 次浏览 • 2017-01-06 19:21 • 来自相关话题

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

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)
}

谷歌开源了一个从 Python 到 Go 的编译器 grumpy

回复

cholerae 发起了问题 • 1 人关注 • 0 个回复 • 429 次浏览 • 2017-01-05 12:21 • 来自相关话题