关于Go,你可能不注意的7件事Golang中文社区(Go语言构建)Go语言中文网Go语言学习园地
Go以简洁著称,但简洁中不乏值得玩味的小细节。这些小细节不如goroutine、interface和channel那样"高大上","屌 丝"得可能不经常被人注意到,但它们却对理解Go语言go语言能做什么有着重要的作用。这里想挑出一些和大家一起通过详实的例子来逐一展开和理解。本文内容较为基础,适合初学者,高手可飘过:)
一、源文件字符集和字符集编码
Go源码文件默认采用Unicode字符集,Unicode码点(code point)和内存中字节序列(byte sequence)的变换实现使用了UTF-8:一种变长多字节编码,同时也是一种事实字符集编码标准,为Linux、MacOSX 上的默认字符集编码,因此使用Linux或MacOSX进行Go程序开发,你会省去很多字符集转换方面的烦恼。但如果你是在Windows上使用 默认编辑器编辑Go源码文本,当你编译以下代码时会遇到编译错误:
//
package main
import "fmt"
func main() {
fmt.Println("中国人")
}
$ go
# command-line-arguments
:6 illegal UTF-8 sequence d6 d0
:6 illegal UTF-8 sequence b9
:6 illegal UTF-8 sequence fa c8
:6 illegal UTF-8 sequence cb 22
:6 newline in string
:7 syntax error: unexpected }, expected )
这是因为Windows默认采用的是CP936字符集编码,也就是GBK编码,“中国人”三个字的内存字节序列为:
“d0d6    fab9    cbc8    000a” (通过iconv转换,然后用od -x查看)
这个字节序列并非utf-8字节序列,Go编译器因此无法识别。要想通过编译,需要将该源文件转换为UTF-8编码格式。
字符集编码对字符和字符串字面值(Literal)影响最大,在Go中对于字符串我们可以有三种写法:
1) 字面值
var s = "中国人"
2) 码点表示法
var s1 = "\u4e2d\u56fd\u4eba"
or
var s2 = "\U00004e2d\U000056fd\U00004eba"
3) 字节序列表示法(二进制表示法)
var s3 = " e4 b8 ad e5 9b bd e4 ba ba"
这三种表示法中,除字面值转换为字节序列存储时根据编辑器保存的源码文件编码格式之外,其他两种均不受编码格式影响。我们可以通过逐字节输出来查 看字节序列的内容:
fmt.Println("s byte sequence:")
for i := 0; i < len(s); i++ {
fmt.Printf("0x%x ", s[i])
}
fmt.Println("")
二、续行
良好的代码style一般会要求代码中不能有太long的代码行,否则会影响代码阅读者的体验。在C中有续行符"\"专门用于代码续行处理;但在 Go中没有专属续行符,如何续行需要依据Go的语法规则(参见Go spec)。
Go与C一样,都是以分号(";")作为语句结束的标识。不过大多数情况下,分号无需程序员手工输入,而是由编译器自动识别语句结束位置,并插入 分号。因此续行要选择合法的位置。下面代码展示了一些合法的续行位置:(别嫌太丑,这里仅仅是展示合法位置的demo)
//details-in-go/
… …
var (
s = "This is an example about code newline," +
"for string as right value"
d = 5 + 4 + 7 +
4
a = [...]int{5, 6, 7,
8}
m = make(map[string]int,
100)
c struct {
m1    string
m2, m3 int
m4    *float64
}
f func(int,
float32) (int,
error)
)
func foo(int, int) (string, error) {
return "",
nil
}
func main() {
if i := d; i >
100 {
}
var sum int
for i := 0; i < 100; i = i +
1 {
sum += i
}
foo(1,
6)
var i int
fmt.Printf("%s, %d\n",
"this is a demo"+
" of fmt Printf",
i)
}
实际编码中,我们可能经常遇到的是fmt.Printf系列方法中format string太长的情况,但由于Go不支持相邻字符串自动连接(concatenate),只能通过+来连接fmt字符串,且+必须放在前一行末尾。另外Gofmt工具会自动调整一些不合理的续行处理,主要针对 for, if等控制语句。
三、Method Set
Method Set是Go语法中一个重要的隐式概念,在为interface变量做动态类型赋值、embeding struct/interface、type alias、method expression时都会用到Method Set这个重要概念。
1、interface的Method Set
根据Go spec,interface类型的Method Set就是其interface(An interface type specifies a method set called its interface)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。