effective go 笔记

本文详细介绍了Go语言的编程规范,包括代码格式化、注释、命名、控制结构、函数、数据类型等关键方面,同时提供了有效的编程技巧和最佳实践建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

格式化

golang 提供了gofmt程序(也可以使用go fmt,它以包为处理对象而非源文件)将go程序按照标准风格缩紧、对齐,保留注释兵在需要时重新格式化;
比如,下面程序你无需花时间将结构体中的字段注释对齐,gofmt 会处理的;

type T struct {
    name string // name of the object
    value int // its value
}

格式化后:

type T struct {
    name    string  // name of the object
    value   int     // its value
}

格式化的细节

  • 缩进

我们使用制表符缩进,gofmt 默认也使用它。在你认为确实有必要时再使用空格

  • 行的长度

Go 对行的长度没有限制,最好不要大于80个字符

  • 括号

控制结构(if for 和switch) 在语法上并不需要圆括号。

注释

  • 支持 C 语言风格注释 /* */
  • C++ 风格的行注释 //。

行注释更为常用,/**/ 主要用于包的注释,当然也可以在禁用一大段代码时使用。
godoc 既是一个程序,又是一个 Web 服务器,它对 Go 的源码进行处理,并提取包中的文档内容。 出现在顶级声明之前,且与该声明之间没有空行的注释,将与该声明一起被提取出来,作为该条目的说明文档。 这些注释的类型和风格决定了 godoc 生成的文档质量。
每个包都应该包含一段包注释,即放在package 之前。对于包含多个文件的包, 包注释只需出现在其中的任一一个文件中即可。包注释应该在整体上对该包进行介绍,并提供包的相关信息。
在程序中,每个可导出的名称都应该有文档注释。文档注释最好是完整的句子,这样它才能适应各种自动化的展示。第一句应当以被声明的东西开头,并且是单句的摘要。

// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func Compile(str string) (regexp *Regexp, err error) {

命名

获取器

不要将Get放到获取器的名字中,既不符合习惯,也没有必要。比如有个名为ower(小写,未导出)的字段,其获取器应当名为Ower(大写,可导出)而非GetOwner。若要提供设置器方法,SetOwner 是个不错的选择。

owner := obj.Owner()
if owner != user {
    obj.SetOwner(user)
}

接口名字

  • 只有一个方法的接口应该以该方法的名字加上 -er后缀来命名, 如Reader、Writer、Formatter、CloseNotifier等。
  • Read、Write、Close、Flush、 String 等都具有典型的签名和意义,除非明确他们的签名和意义,否则不要使用。

驼峰记法

Go 中约定使用驼峰记法 MixedCaps 或 mixedCaps 而非下划线的方式来对单词名称进行命名。

分号

Go 语言也是分号结尾的,只是词法分析器按照简单的规则自动插入分号,我们写代码的适合就不需要手动添加了;这条规则是“如果新行前的最后一个标记为标识符(包括int 和 float64 这类的单词)、数值或者字符串常量之类的基本子面或以下标记之一

break continue fallthrough return ++ – ) }

则词法分析就在最后插入分号。”

  • 分号在大括号之前直接省略。
  • 不能将控制结构的左大括号放在下一行

for

与C类比
// c for
for init; condition; post {}
// c while
for condition {}
// c for( ;; )
for {}

switch

switch 多个条件相同处理方式,可以用逗号列举

func shouldEscape(c byte) bool {
	switch c {
		case ' ', '?', '&', '=', '#', '+', '%':
		return true
	}
	return f
}

break 搭配标签可以退出循环;
continue 也可以搭配标签,不过必须要要在循环中;

函数

可命名返回结果

  • Go的函数的返回结果可被命名,在函数执行的适合会将命名参数初始化其相应的零值。
  • 如果没有明确返回,命名参数的当前值就是返回结果。

Defer

  • 执行顺序LIFO。
  • 求值是在推迟执行时进行,而非在调用推迟函数时。

Data

new 与 make

new : 用来分配内存的内建函数,但是不会初始化内存,只是将内存设置为零值。
make : 只用于创建slice map 和channel ,并返回一个类型为T(而非 *T)的已经初始化(而非零值)的值。

数组

在Go中:

  • 数组是值。将一个数组赋予另一个数组会复制其所有元素。
  • 将某个数组传入某个函数,它将收到该数组的一个副本而非指针。
  • 数组的大小是其类型的一部分。类型[10]int 和 [20]int是不同的类型。

切片

  • 切片是对数组的引用。
  • 切片的容量可通过内建函数cap获得,它将给出该切片可获取的最大长度。
  • 超出容量,会重新分配切片。
  • append 可修改slice 的元素,但是切片自身(其运行时数据结构包含指针、长度和容量)是通过值传递的。

map

  • 健可以是任何可以支持相等性操作的类型,切片不可以;
  • 试图获取不存在的值,返回该类型的零值;

打印

  • %d : 十进制
  • %x : 十六进制
  • %v : 通用格式,打印值
    &{7 -2.35 abc def}
  • %+v : 给值添加上字段名
    &{a:7 b:-2.35 c:abc def}
  • %#v : 完全按照Go语法打印。
    &main.T{a:7, b:-2.35, c:“abc\tdef”}
  • %T : 打印类型

参考

effiective go

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值