两个Go语言编程小技巧

本文介绍两个Go编程中的小技巧。

技巧1:如何模拟一些其它语言中支持的for i in 0..N循环代码块

我们可以使用一个for-range循环遍历一个尺寸为零的数组值来模拟for i in 0..N。比如,下面这个循环将打印出0到9这十个数字。

  for i := range [10]struct{}{} {
    fmt.Println(i)
  }

虽然这个技巧中的循环的字符数比下面这个多,但是我发现此技巧中的代码敲起来比下面这个这段代码顺手。

  for i := 0; i < 10; i++ {
    fmt.Println(i)
  }

仁者见仁,很多程序员可能还是更推荐使用此传统的for循环。

注意,数组类型[10]struct{}的尺寸为零。如果一个数组类型的元素类型的尺寸为零,则此数组类型的尺寸也必然为零,无论此数组类型的长度为多大。另外,一个长度为零的数组类型的尺寸总为零,无论此数组的元素类型的尺寸有多大。(一个类型的尺寸是指此类型的任何一个值在内存中需要多少字节存储。)

技巧2:如何声明一个不可比较的结构体类型

有时候我们不希望自己写的代码库中的某个结构体类型被用作映射(map)类型的键值类型,或者不希望此结构体类型的值被(使用==)比较。这时,我们可以在此结构体类型中添加一个类型为不可比较类型的字段。

再进行下一段之前,让我们理一下Go中什么类型为不可比较类型。一个不可比较类型是指此类型的值不能相互比较。在Go中,下列类型为不可比较类型:

  • 切片类型
  • 映射(map)类型
  • 函数类型
  • 元素类型为不可比较类型的数组类型
  • 任一字段的类型为不可比较类型的结构体类型

所以,我们只需给一个结构体类型加一个类型为上述不可比较类型的字段,则此结构体类型也将成为一个不可比较类型。更完美一点,我们可以用一个尺寸为零的不可比较类型做为此字段的类型,以防止此字段增大此结构体类型的尺寸。比如,下面这个结构体类型T的字段dummy的类型为一个尺寸为零的不可比较类型[0]func(),从而使得结构体类型T不可比较并且没有因此而增大尺寸。

type T struct {
  dummy        [0]func()
  AnotherField int
}

这里的数组类型[0]func()不可比较是因为它的元素类型func()不可比较。

验证一下这个类型是否可以比较:

package main

type T struct {
  dummy        [0]func()
  AnotherField int
}

func main() {
  var x, y T
  println(x == y)
}

运行之,得到如下报错:

$ go run main.go
# command-line-arguments
./main.go:10:12: invalid operation: x == y (struct containing [0]func() cannot be compared)

更多关于Go语言的细节、技巧和常识,请访问《Go语言101》项目或者《Go语言101》官网,或者关注本专栏公众号(Go 101):

Go 101.jpg

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算与大数据

Dubbo for Go,Ready for Now.

多语言支持是 Dubbo 发展生态的重点之一。目前,Dubbo 已经支持 PHP/Node.js/Python,同时,基于标准的 Java REST API -...

26930
来自专栏毛毛v5

利用vscode当golang编写IDE的配置过程

vscode以良好的兼容性进来收到追捧。整个vscode执行效率比基于java的ide效率又高。一直用liteide来编写golang,但是liteide调试时...

30420
来自专栏毛毛v5

golang type struct 只写成员类型的 匿名字段。

这真是蛋疼了。*sql.DB是什么鬼啊?为什么只有类型没有字段名啊?看来没有系统看过golang语法真是够呛。发个QQ在群里面问golang达人,趁着别人还没回...

9920
来自专栏每日一篇技术文章

go-runtime/pprof

开始之前先下载性能文件分析工具,下载地址: http://www.graphviz.org/download/

15120
来自专栏毛毛v5

golang db.Prepare select top ? order by ?

用的这个驱动 _ "github.com/go-sql-driver/mysql" 经过测试,貌似golang的 db.Prepare在查询字符串中 不能使用...

12950
来自专栏毛毛v5

golang的func的一些笔记

其中: 关键字———func // 这个是定义函数的关键字 函数拥有者—(p myType) // 这个是此函数的拥有者,下面解释(此项可省略) 方法名...

16730
来自专栏每日一篇技术文章

命令源码文件

定义:命令源码文件是程序的原型入口,是每个可独立运行的程序必须拥有的,我们可以通过构建和安装生成对应的可执行文件,后者一般与该命令源码文件的直接父目录同名

15030
来自专栏每日一篇技术文章

go-runtime/trace

执行追踪器,跟踪器捕获各种各样的时间,如go协程的创建、阻塞、解锁,syscall 进入、退出、阻塞、GC相关时间,堆大小变化,处理器启动、停止等,将这些事件写...

8410
来自专栏每日一篇技术文章

工作区介绍

1.一个代码包可以有多个以.go为扩展名的源码文件组成如下,demo1.go demo2.go 和 main.go 都属于代码包main,注意同一个目录下的.g...

11820
来自专栏每日一篇技术文章

协程锁

我们对一个变量total 进行1000次 +1 操作,不过我们是在多个协程中进行的,猜猜结果如何,我们运行五次看结果

9620

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励