两个Go语言编程小技巧

以下文章来源于Go 101 ,作者老貘

本文介绍两个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 

仁者见仁,很多程序员可能还是更推荐使用此传统的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》官方网站:https://gfw.go101.org (可点击下面的原文链接直接访问)。

10