Windows上的 *wchar_t 问题,C.GoString() , issues/1691 现在有最优解么?

回复

有问必答fino 发起了问题 • 1 人关注 • 0 个回复 • 674 次浏览 • 2016-11-20 11:59 • 来自相关话题

Mgo复杂查询实例

文章分享ck_wizard 发表了文章 • 0 个评论 • 610 次浏览 • 2016-11-17 17:44 • 来自相关话题

** 写这边文章是由于自己经常忘记, 所以放在这里来帮助记忆,也方便大家

1.首先声明3个结构

type Str... 			查看全部
					

** 写这边文章是由于自己经常忘记, 所以放在这里来帮助记忆,也方便大家


1.首先声明3个结构


type Struct1 struct {
Id string `bson:"_id"`
S2 []Struct2
}

type Struct2 struct {
Id string `bson:"_id"`
S3 []Struct3
}

type Struct3 struct {
Id string `bson:"_id"`
Value string
}

** 1.创建


首先先创建二个结构1 1,2
在为每个结构一创建二个结构1,2
在为每个结构二创建二个结构三1,2


这里需要注意
使用操作符$addToSet去向数组里面插入数据,如果使用$Set去写入数据,着会把格式变为结构中嵌套结构
例:


func AddS2(str1 *Struct1, str2 *Struct2) bool {
change := bson.M{"$addToSet": bson.M{"s2": str2}}

exop := func(c *mgo.Collection) error {
return c.UpdateId(str1.Id, change)
}

err := witchCollection(TableName, exop)

return !tools.HaveError("加入结构2错误", 49, err)
}

在创建结构3的时候查找语句是这样的


    query := bson.M{"_id": str1.Id, "s2._id": str2.Id}
change := bson.M{"$addToSet": bson.M{"s2.$.s3": str3}}

直接搜索数组s2,Id符合要求的结构
$美元符号,在update中,可理解为数组下标


最后建立了一张表结构为
Photo1


** 2.删除子项


//删除放在前面,是因为我需要做删除功能了.
2.1 删除结构三之1
使用代码


func DelS3(str1 *Struct1, str2 *Struct2, str3 *Struct3) bool {
query := bson.M{"_id": str1.Id, "s2._id": str2.Id, "s2.s3._id": str3.Id}

change := bson.M{"$pull": bson.M{"s2." + str2.Id + ".s3": str3}}

exop := func(c *mgo.Collection) error {
return c.Update(query, change)
}

err := witchCollection(TableName, exop)

return !tools.HaveError("删除结构3错误", 49, err)
}

可以看到的细节
1.使用了$pull
2.change语句在获取s2数组时使用了下标


直接删除一个结构用的.s3,那么要删除结构下面的一个元素就可以用.s3.value,来进行删除了.


数据库结果为


Photo2


可以看到id1=2&id2=2&id3=1的结构没有了.


这里有一个细节,当使用数组的数组的时候$代表的是一个个数组的下表,不是第二个,所以你还需要计算第二个数组下表的位置.才能正确查询


最后附上非常重要的数组标志表,官方 英文







































Name Description
$ Acts as a placeholder to update the first element that matches the query condition in an update.
$addToSet Adds elements to an array only if they do not already exist in the set.
$pop Removes the first or last item of an array.
$pullAll Removes all matching values from an array.
$pull Removes all array elements that match a specified query.
$pushAll Deprecated. Adds several items to an array.
$push Adds an item to an array.

beego 表单验证 validation通过 StructTag 递归验证 组合struct

回复

有问必答gloomyzerg 发起了问题 • 1 人关注 • 0 个回复 • 1031 次浏览 • 2016-11-17 14:59 • 来自相关话题

beego orm 求支持sql注释

回复

有问必答robi 发起了问题 • 1 人关注 • 0 个回复 • 960 次浏览 • 2016-11-17 12:32 • 来自相关话题

视频教程:玩转数人云Mesos调度器Swan

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

数人云开源第二弹!

数人云Mesos调度器Swan开源已经... 查看全部

数人云开源第二弹!


数人云Mesos调度器Swan开源已经一周多了,收到很多小伙伴的帮助和反馈,小数在这里表示感谢^_^
数人云工程师为Swan的使用录制了视频,帮助大家更好更快地了解Swan。


视频地址:http://v.qq.com/x/page/r0346559nfx.html


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


关于Swan


Swan基于Mesos Restful API编写的应用调度框架,可以帮助用户轻松发布应用,实现应用的滚动更新,并根据用户指定的策略做应用的健康检测和故障转移。未来,数人云Swan团队还将努力实现调度策略、高可用服务发现、网络管理、编排,以及任务抢占等功能。

学习 golang 中,写了个 golang http client 练练手

开源程序cizixs 发表了文章 • 0 个评论 • 505 次浏览 • 2016-11-17 11:05 • 来自相关话题

项目地址: https://github.com/cizixs/gohttp

最近在学习 golang ,用 net/http 写一个 http ... 查看全部

项目地址: https://github.com/cizixs/gohttp


最近在学习 golang ,用 net/http 写一个 http 客户端的时候,发现有事事情写起来很复杂。就想着自己封装一个更易用的库,正好也练练手。


目前的功能已经包括:



  • 支持所有的 HTTP method

  • 可以设置 HTTP Header

  • 能够直接添加 query string

  • 动态拼接 url path

  • 发送 form 和 json 数据

  • 从 response 中读取对应格式的数据: string , bytes , json

  • 允许设置请求 timeout 时间

  • 允许手动设置代理

  • 支持简单地用户密码认证


后面也计划了挺多功能,希望慢慢实现。


代码比较简单,也都添加了注释。想学习 golang 的同学可以看看,欢迎试用。如果有想入门 golang http 编程的,也可以考虑后面补充几篇博客讲讲这块内容。


如果在使用过程中遇到什么问题,直接在 github 上创建 issue 就行,我会及时跟进和回复的。

TiDB Weekly [2016.11.14]

Go开源项目qiuyesuifeng 发表了文章 • 0 个评论 • 441 次浏览 • 2016-11-16 22:53 • 来自相关话题

Last week, we landed 查看全部

Last week, we landed 25 PRs in the TiDB repositories, 5 PRs in the TiDB docs repositories.


Weekly update in TiDB


Added



Fixed



Improved



Document change



Weekly update in TiKV


Last week, we landed 23 PRs in the TiKV repositories.


Added




  • Resolve locks in batches to avoid generating a huge Raft log when a transaction rolls back.




  • Add applying snapshot count to enhance the Placement Driver (PD) balance, with PR 1278, 381.



  • Check the system configuration before startup.


Fixed



Improved



原文链接

golang 基础之 import 详解

文章分享xieyanke 发表了文章 • 0 个评论 • 601 次浏览 • 2016-11-16 16:55 • 来自相关话题

import

golang 中的模块是通过 package 进行组织管理的,通过 import 进行导入的

几种包的导入形式:

  1. 导入标准库... 查看全部

import



golang 中的模块是通过 package 进行组织管理的,通过 import 进行导入的



几种包的导入形式:



  1. 导入标准库

    • import "fmt",是最常用导入标准的形式

    • import f "fmt",为标准库起一个别名,而后调用 fmt.Println("") 可以使用 f.Println("")

    • import . "fmt",将 fmt 启用别名".",这样就可以直接使用其内容,而不用再加 fmt,例如fmt.Println("") 可以直接写成 Println("")


  2. 导入私人库

    • import "samples/util" 这里 samples 目录位于 $GOPATH/src 的目录下,import 之后就可以通过util.XXX 使用 util 包中提供的内容,包的名字并不是由其所在的目录定义的,而是由 package 关键字定义的,例如:util 目录下每个 *.go 文件中都定义 package tools,那么在 import "samples/util" 之后需要使用实际包的名称调用即: tools.XXX,同一个目录下只允许定义一个包名,推荐与所在目录名称相同。

    • import _ "samples/util",表示不使用该包,而是只是使用该包的 init 函数,即在 import 时执行 util 包中的 init 函数,如果 util 包中有多个 init 函数,不同 .go 文件之间的多个 init 函数的执行顺序按所属 .go 的文件名称的字典排序的顺序执行,同一 *.go 文件中的多个 init 函数之间的执行顺序按由上到下执行。


建议

站点反馈lifesohard 发表了文章 • 0 个评论 • 368 次浏览 • 2016-11-14 13:53 • 来自相关话题

建议创建一个精华文章系列

建议创建一个精华文章系列

golang利用模板生成数据库表对应的模型及操作函数

文章分享changjixiong 发表了文章 • 0 个评论 • 778 次浏览 • 2016-11-13 19:05 • 来自相关话题

起因


  很多年以前,当我第一次接触到ORM的时候,我就有一点疑惑:这玩意用起来倒是方便,就是模型结构得一个字段一个字段的写,非常枯燥也非常累人,而且如果表结构修改了,比如增加、减少或者修改了一个字段,就得修改模型文件。那... 查看全部

起因




  很多年以前,当我第一次接触到ORM的时候,我就有一点疑惑:这玩意用起来倒是方便,就是模型结构得一个字段一个字段的写,非常枯燥也非常累人,而且如果表结构修改了,比如增加、减少或者修改了一个字段,就得修改模型文件。那个时候也没有想到可以从数据库中读取到目标表的表结构数据自动生成ORM需要的模型结构。直到有一天我看到一个根据模板自动生成ORM的模型文件的代码,然后我就用golang也写了这么一个玩意。完整的代码在这里
  


生成过程


准备工作




  假设我在mysql中创建了一个名为dbnote的库,并且创建了一个名为msg的表,创建语句如下:


CREATE TABLE msg (
id int(11) NOT NULL AUTO_INCREMENT,
sender_id int(11) NOT NULL COMMENT '发送者',
receiver_id int(11) NOT NULL COMMENT '接收者',
content varchar(256) NOT NULL COMMENT '内容',
status tinyint(4) NOT NULL,
createtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);

那么对应的ORM模型则是


type Msg struct {
ID int `db:"id" json:"id"` //
SenderID int `db:"sender_id" json:"sender_id"` // 发送者
ReceiverID int `db:"receiver_id" json:"receiver_id"` // 接收者
Content string `db:"content" json:"content"` // 内容
Status int8 `db:"status" json:"status"` //
Createtime *time.Time `db:"createtime" json:"createtime"` //
}

  


获取表结构信息




  为了生成这个struct以及相关的增删改查代码,我需要先获得这个表的结果信息,以及编写对应的模板文件用于代码生成。
  通过查询语句


SELECT table_name from tables where table_schema='dbnote'

可以获取到这个库中所有的表名(当然,也可以增加过滤条件筛选目标表)。


  用目标表的名称通过查询语句


SELECT COLUMN_NAME,DATA_TYPE,COLUMN_KEY,COLUMN_COMMENT from COLUMNS 
where TABLE_NAME='msg' and table_schema = 'dbnote'

可以获取这个表的结构信息。
表结构的信息用这样一个struct存储


type TABLE_SCHEMA struct {
COLUMN_NAME string `db:"COLUMN_NAME" json:"column_name"`
DATA_TYPE string `db:"DATA_TYPE" json:"data_type"`
COLUMN_KEY string `db:"COLUMN_KEY" json:"column_key"`
COLUMN_COMMENT string `db:"COLUMN_COMMENT" json:"COLUMN_COMMENT"`
}

生成模型及操作函数需要的全部信息,则用这样一个struct存储


type ModelInfo struct {
BDName string
DBConnection string
TableName string
PackageName string
ModelName string
TableSchema *[]TABLE_SCHEMA
}

  


生成struct




  初始化模板对象的代码是这样的


data, _ := ioutil.ReadFile("../modeltool/model.tpl")
render := template.Must(template.New("model").
Funcs(template.FuncMap{
"FirstCharUpper": modeltool.FirstCharUpper,
"TypeConvert": modeltool.TypeConvert,
"Tags": modeltool.Tags,
"ExportColumn": modeltool.ExportColumn,
"Join": modeltool.Join,
"MakeQuestionMarkList": modeltool.MakeQuestionMarkList,
"ColumnAndType": modeltool.ColumnAndType,
"ColumnWithPostfix": modeltool.ColumnWithPostfix,
}).
Parse(string(data)))

函数的定义参见代码


  填充好一个ModelInfo对象后,就可以生成代码文件了


if err := render.Execute(f, model); err != nil {
log.Fatal(err)
}
fmt.Println(fileName)
cmd := exec.Command("goimports", "-w", fileName)
cmd.Run()

最后用goimports添加需要import的package,并且goimports竟然连format工作都做了,简直太爽。
  


相关模板语法说明





  • 以下语句将ModelName的值用函数FirstCharUpper处理为首字面大写然后赋值给$exportModelName变量
    {{$exportModelName := .ModelName | FirstCharUpper}}

  • 以下语句使用变量$exportModelName
    type {{$exportModelName}} struct


  • 以下语句通过函数ExportColumn将字段COLUMN_NAME的值中的下画线去掉并将单词的首字面大写,并且将id处理成ID。ExportColumn内容参见代码,可以根据实际需要调整。


    {{.COLUMN_NAME | ExportColumn}}


  • 以下语句循环处理ModelInfo.TableSchema中的元素
    {{range .TableSchema}} {{.COLUMN_NAME | ExportColumn}} {{.DATA_TYPE | TypeConvert}} {{.COLUMN_NAME | Tags}} // {{.COLUMN_COMMENT}}
    {{end}}}

  • 以下语句用3个参数 .PkColumns,=?, and调用函数ColumnWithPostfix
    {{ColumnWithPostfix .PkColumns "=?" " and "}}"

    函数的定义是


    func ColumnWithPostfix(columns []string, Postfix, sep string) string {
    result := make([]string, 0, len(columns))
    for _, t := range columns {
    result = append(result, t+Postfix)
    }
    return strings.Join(result, sep)
    }

  • 以下语句是另外一种风格的循环
    {{range $K:=.PkColumns}}{{$K}},
    {{end}}

    增删改查代码的自动生成没有什么需要特别说明的,具体参见代码



一点说明


  代码的目录结构是这样的


|____dbnotes
| |____dbhelper
| | |____dbhelper.go
| |____dbnote.go
| |____init.go
| |____model
| | |____mail.go
| | |____msg.go
| | |____notice.go
| |____modelgenerator
| | |____modelgenerator.go
| |____modeltool
| | |____model.tpl
| | |____modeltool.go

  modelgenerator.go 编译后,运行modelgenerator可根据model.tpl将struct及操作函数生成源码文件,存放在model目录下mail.go、msg.go、notice.go的这3个源码文件就是自动生成的。3个表的创建命令在init.go的注释代码中。
  数据库IP地址,用户名及密码在dbhelper.go的init()函数中,DB实例用于连接mail、msg、notice所在的库,SYSDB实例用于连接information_schema库获取表结构信息。
  dbnote.go是示例代码,示范对mail、msg、notice3个表数据的增删改查。


一点问题


  由于golang的基本类型都有一个默认的初始值,不存在定义后没有初始化的变量。所以对于数据库中的NULL就没有一个比较好的直接处理的方式,如果将struct中的数据类型定义为类似这样


Content    *string 

倒是可以接收有内容的值以及NULL,但是这样以来,对于Content的取值和赋值就没那么方便了,当然也可以用NullString。鉴于golang的基本类型都有一个默认的初始值,我个人觉得表里面还是设定为不接受NULL值比较好。

好玩的github项目-go语言统计github上面各个编程语言每月的新增或者更新的数量

Go开源项目wwdyy 发表了文章 • 0 个评论 • 697 次浏览 • 2016-11-13 10:47 • 来自相关话题

转自github用户Emmanuel Keller

统计满足的条件:

每个语言/每月

至少一颗星 至少一个fork 大于 10 Kb

github地址:查看全部

转自github用户Emmanuel Keller


统计满足的条件:


每个语言/每月


至少一颗星
至少一个fork
大于 10 Kb


github地址:https://github.com/emmanuel-keller/github-language-statistics

[译]Go里面的unsafe包详解

回复

文章分享astaxie 发起了问题 • 7 人关注 • 0 个回复 • 2480 次浏览 • 2016-11-13 09:07 • 来自相关话题

google/gops:一个列出和诊断系统中正在运行Go 进程的命令行工具。

回复

文章分享astaxie 发起了问题 • 5 人关注 • 0 个回复 • 1572 次浏览 • 2016-11-12 20:45 • 来自相关话题

RobotGo v0.30.0,Golang跨平台控制鼠标键盘位图屏幕,全局事件监听,增加窗口句柄

回复

文章分享veni 发起了问题 • 1 人关注 • 0 个回复 • 892 次浏览 • 2016-11-10 20:45 • 来自相关话题

Go1.7里面的BCE(跳跃检测排除)(译)

文章分享astaxie 发表了文章 • 0 个评论 • 650 次浏览 • 2016-11-10 19:10 • 来自相关话题

最近发布的 Go 1.7 里面使用了一个新的基于 SSA 的编译后端(目前只有 amd64 可用)。SSA 使得编译出来的代码更加高效 SSA,主要是里面有包含了 查看全部

最近发布的 Go 1.7 里面使用了一个新的基于 SSA 的编译后端(目前只有 amd64 可用)。SSA 使得编译出来的代码更加高效 SSA,主要是里面有包含了 BCE公共子表达式消除


这篇文章将会通过一些例子给大家展示 Go 1.7 里面BCE是如何工作的。


在 Go 1.7 里面我们可以通过这个命令 go build -gcflags="-d=ssa/check_bce/debug=1" 来展示我们的代码哪一行需要进行越界检查。


例子1


// example1.go
package main

func f1(s []int) {
_ = s[0] // line 5: bounds check
_ = s[1] // line 6: bounds check
_ = s[2] // line 7: bounds check
}

func f2(s []int) {
_ = s[2] // line 11: bounds check
_ = s[1] // line 12: bounds check eliminatd!
_ = s[0] // line 13: bounds check eliminatd!
}

func f3(s []int, index int) {
_ = s[index] // line 17: bounds check
_ = s[index] // line 18: bounds check eliminatd!
}

func f4(a [5]int) {
_ = a[4] // line 22: bounds check eliminatd!
}

func main() {}

$ go build -gcflags="-d=ssa/check_bce/debug=1" example1.go
# command-line-arguments
./11.go:5: Found IsInBounds
./11.go:6: Found IsInBounds
./11.go:7: Found IsInBounds
./11.go:11: Found IsInBounds
./11.go:17: Found IsInBounds

我们可以看到这个f2函数里面的12行和13行不需要进行越界检查,因为在11行里面的越界检查可以保证12,13行的代码是不会越界的。


但是在f1里面必须每一行都逐一检查越界,因为第5行没办法保证第6、第7行是安全的,第6行没办法保证第7行是安全的。


函数f3里面,Go 1.7 编译器知道如果第一行是安全的情况下,那么第二行的s[index]是完全安全的


Go 1.7 的编辑器也正确的分析出来了f4函数里面的唯一的一行(22行)也是安全的。


例子2


// example2.go
package main

func f5(s []int) {
for i := range s {
_ = s[i]
_ = s[i:len(s)]
_ = s[:i+1]
}
}

func f6(s []int) {
for i := 0; i < len(s); i ++ {
_ = s[i]
_ = s[i:len(s)]
_ = s[:i+1]
}
}

func f7(s []int) {
for i := len(s) - 1; i >= 0; i -- {
_ = s[i] // line 22: bounds check
_ = s[i:len(s)]
}
}

func f8(s []int, index int) {
if index >= 0 && index < len(s) {
_ = s[index]
_ = s[index:len(s)]
}
}

func f9(s []int) {
if len(s) > 2 {
_, _, _ = s[0], s[1], s[2]
}
}

func main() {}

$ go build -gcflags="-d=ssa/check_bce/debug=1" example2.go
# command-line-arguments
./11.go:22: Found IsInBounds

我们可以看到在例子2里面只有一行需要进行越界检查


Go 1.7 编译器是如此的聪明,它精确的做出决定说:在f5和f6里面所有的代码都是安全的


但是好像还是没有我们人类聪明,看上去22行也是安全的


例子3


// example3.go
package main

import "math/rand"

func fa() {
s := []int{0, 1, 2, 3, 4, 5, 6}
index := rand.Intn(7)
_ = s[:index] // line 9: bounds check
_ = s[index:] // line 10: bounds check eliminatd!
}

func fb(s []int, index int) {
_ = s[:index] // line 14: bounds check
_ = s[index:] // line 15: bounds check // not smart enough or a bug?
}

func fc() {
s := []int{0, 1, 2, 3, 4, 5, 6}
s = s[:4]
index := rand.Intn(7)
_ = s[:index] // line 22: bounds check
_ = s[index:] // line 23: bounds check
}

func main() {}

$ go build -gcflags="-d=ssa/check_bce/debug=1" example3.go
# command-line-arguments
./11.go:9: Found IsSliceInBounds
./11.go:14: Found IsSliceInBounds
./11.go:15: Found IsSliceInBounds
./11.go:22: Found IsSliceInBounds
./11.go:23: Found IsSliceInBounds

啊!那么多地方需要进行越界检查


但是等等,为什么 Go 1.7 的编译器会认为第10行是安全的,但是15行和23行不安全?是因为编译器不够聪明还是这是一个bug?


实际上,编译器在这里是对的!为什么?原因是子slice可能大于原始的slice,看下面这个例子:


package main

func main() {
s0 := make([]int, 5, 10) // len(s0) == 5, cap(s0) == 10

index := 8

// In golang, for the subslice syntax s[a:b],
// the valid rage for a is [0, len(s)],
// the valid rage for b is [a, cap(s)].

// So, this line is no problem.
_ = s0[:index]
// But, above line is safe can't assure the following line is also safe.
// In fact, it will panic.
_ = s0[index:] // panic: runtime error: slice bounds out of range
}

所以如果s[:index]是安全的话,也就当len(s) == cap(s)的时候,s[index:]才是安全的
。这就是为什么在例子3里面fb和fc里面的代码还需要进行越界检查。


Go 1.7 编译器在函数fa里面成功的检测到了 len(s) == cap(s)。太棒了!Golang Team!


然而,如果s[index:]是安全的话,那么s[:index]就一直是安全的。


例子4


// example4.go
package main

import "math/rand"

func fa2() {
s := []int{0, 1, 2, 3, 4, 5, 6}
index := rand.Intn(7)
_ = s[index:] // line 9: bounds check
_ = s[:index] // line 10: bounds check eliminatd!
}

func fb2(s []int, index int) {
_ = s[index:] // line 14: bounds check
_ = s[:index] // line 15: bounds check // not smart enough?
}

func fc2() {
s := []int{0, 1, 2, 3, 4, 5, 6}
s = s[:4]
index := rand.Intn(7)
_ = s[index:] // line 22: bounds check
_ = s[:index] // line 23: bounds check eliminatd!
}

func main() {}

$ go build -gcflags="-d=ssa/check_bce/debug=1" example4.go
# command-line-arguments
./11.go:9: Found IsSliceInBounds
./11.go:14: Found IsSliceInBounds
./11.go:15: Found IsSliceInBounds
./11.go:22: Found IsSliceInBounds

在这个例子中, Go 1.7 编译器成功的计算出来在fc2函数里面如果22行安全的情况下那么23行也是安全的,但是在fb2里面没办法计算出来如果14行安全的情况下15行也是安全的情况。


例子5


尽管当前的编译器(Go1.7.1 amd64) 还是不够智能的排除一些不需要检测的地方,但是我们可以做一些暗示来帮助编译器排除这些不必要的越界检查。


// example5.go
package main

func fd(is []int, bs []byte) {
if len(is) >= 256 {
for _, n := range bs {
_ = is[n] // line 7: bounds check, not smart enough.
}
}
}

func fd2(is []int, bs []byte) {
if len(is) >= 256 {
is = is[:256] // line 14: bounds check. A hint for the compiler.
for _, n := range bs {
_ = is[n] // line 16: bounds check eliminatd!
}
}
}

func fe(isa []int, isb []int) {
if len(isa) > 0xFFF {
for _, n := range isb {
_ = isa[n & 0xFFF] // line 24: bounds check, not smart enough.
}
}
}

func fe2(isa []int, isb []int) {
if len(isa) > 0xFFF {
isa = isa[:0xFFF+1] // line 31: bounds check. A hint for the compiler.
for _, n := range isb {
_ = isa[n & 0xFFF] // line 33: bounds check eliminatd!
}
}
}

func ff(s []int) []int {
s2 := make([]int, len(s))
for i := range s {
s2[i] = -s[i] // line 41: bounds check, not smart enough.
}
return s2
}

func ff2(s []int) []int {
s2 := make([]int, len(s))
s2 = s2[:len(s)] // line 48: bounds check. A hint for the compiler.
for i := range s {
s2[i] = -s[i] // line 50: bounds check eliminatd!
}
return s2
}

func main() {}

$ go build -gcflags="-d=ssa/check_bce/debug=1" example5.go
# command-line-arguments
./11.go:7: Found IsInBounds
./11.go:14: Found IsSliceInBounds
./11.go:24: Found IsInBounds
./11.go:31: Found IsSliceInBounds
./11.go:41: Found IsInBounds
./11.go:48: Found IsSliceInBounds

总结


尽管当前1.7版本里面的 BCE 特性还不够完美,但是在大多数情况下还是表现的非常好。毫无疑问Go的编译器将会在后续版本里面做的更好,感谢 Go 团队增加了如此帮的特性


参考文献



  1. gBounds Checking Elimination

  2. Utilizing the Go 1.7 SSA Compiler


原文:http://www.tapirgames.com/blog/golang-1.7-bce