Go 语言简介、编程规范与零散知识点

Go 语言简介、编程规范与零散知识点

Go 语言简介

Go 语言的历史

  • Go 1.5 版本:2015 年 8 月发布,具有历史性意义。完全移除了 C 语言部分,实现了用 Go 编译 Go,仅少量代码使用汇编实现。同时,谷歌邀请内存管理专家 Rick Hudson 重新设计 GC,支持并发 GC,解决了 GC 时延(STW)问题。到 Go 1.8 时,GC 时延已从 Go 1.1 的数秒控制在 1ms 以内。

语言特性与版本兼容

  • 在 Go 语言的版本迭代中,语言特性基本维持在 Go 1.1 基准上,官方承诺新版本对老版本开发的代码完全兼容。
  • Go 开发团队在新增语言特性上十分谨慎,而在稳定性、编译速度、执行效率以及 GC 性能等方面持续优化。

谷歌工程师的 20% 时间

  • 谷歌的 “20% 时间” 工作方式允许工程师拿出 20% 的时间研究自己喜欢的项目,Go 语言最初便是这一工作方式的产物。

Go 语言优势

  • 高效的并发编程:通过 goroutine 和 channel 提供原生的并发编程支持。
  • 内存安全:自动垃圾回收机制有效管理内存,减少内存泄漏和段错误问题。
  • 快速编译和部署:编译速度快,可快速构建和部署应用程序。
  • 强大的标准库:涵盖网络编程、并发控制、加密解密、文件操作等各方面功能和工具。

Go 语言特性总结

  • 规范的语法:不需要符号表来解析。
  • 垃圾回收:独有垃圾回收机制。
  • 无头文件
  • 明确的依赖
  • 无循环依赖
  • 常量只能是数字
  • int 和 int32 是两种类型
  • 字母大小写设置可见性
  • 任何类型都有方法
  • 没有子类型继承
  • 包级别初始化以及明确的初始化顺序
  • 文件被编译到一个包里
  • 没有数值类型转换
  • 接口隐式实现
  • 嵌入:不会提升到超类。
  • 方法按照函数声明
  • 方法即函数
  • 接口只有方法
  • 方法通过名字匹配
  • 没有构造函数和析构函数
  • postincrement(如 ++i)是状态
  • 没有 preincrement (i++) 和 predecrement
  • 赋值不是表达式
  • 明确赋值和函数调用中的计算顺序
  • 没有指针运算
  • 内存一直以零值初始化
  • 局部变量取值合法
  • 方法中没有 “this”
  • 分段的堆栈
  • 没有静态和其它类型的注释
  • 没有模板
  • 内建 string、slice 和 map
  • 数组边界检查

Go 零散知识点

交叉编译与国际化

  • 交叉编译:可在运行 Linux 系统的计算机上开发运行 Windows 下的应用程序。
  • 国际化:Go 语言完全支持 UTF-8,源码文件格式也使用 UTF-8 编码。

Go 语言的标识符规则

  • 导出标识符:以大写字母开头的标识符可被外部包的代码使用。
  • 包内可见标识符:以小写字母开头的标识符对包外不可见。

协程与通讯

  • 协程调度:协程间一般由应用程序显式实现调度,上下文切换无需下到内核层。
  • 协程通讯方式
    • 共享内存型:使用全局变量 + mutex 锁实现数据共享。
    • 消息传递型:使用独有的 channel 机制进行异步通讯。

GC(垃圾回收)

  • GC 过程:先 stop the world,扫描所有对象判活,标记可回收对象,恢复服务,同时起一个专门 goroutine 回收内存。
  • GC 瓶颈:每次都要扫描所有对象来判活,待收集的对象数目越多,速度越慢。

网络编程

  • Go 语言提供丰富便捷的网络编程接口,如:
    • socketnet.Dial
    • httphttp.Get/Post()
    • rpcclient.Call('class_name.method_name', args, &reply)

Cgo 与语言交互

  • Cgo:Go 语言直接重用了大部份的 C 模块,称为 Cgo。
  • 与 C++ 交互替代方案
    • 先将 C++ 编译成动态库,再由 Go 调用一段 C 代码。
    • 使用 swig。

包引用规则

  • 不能循环引用,避免潜在编程危险。

变量

  • 变量定义了就要使用,否则无法通过编译。
  • 在相同的代码块中,不可以再次对于相同名称的变量使用初始化声明。

defer 机制

  • Go 语言提供关键字 defer,可指定延迟执行的逻辑体,在函数体 return 前或出现 panic 时执行。

测试源码文件

  • 测试源码文件以 _test.go 结尾,使用 Go 的内置测试框架 testing

测试函数

  • 功能测试函数:名称以 Test 为名称前缀的函数,只能接受 *testing.T 的参数。
  • 性能测试函数:名称以 Benchmark 为名称前缀的函数,只能接受 *testing.B 的参数。

编程规范

一、包相关规范

  • 包名:保持 package 的名字和目录一致,尽量采用简短且有意义的包名。
  • 包注释:每个包都要有包注释,位于 package 子句之前。

二、文件命名规范

  • 文件名应简短且有意义,由小写单词组成,使用下划线分隔各个单词。

三、结构体相关规范

  • 命名:采用驼峰命名法,首字母根据访问控制大写或者小写。
  • 申明和初始化格式:采用多行。

四、接口相关规范

  • 命名:规则基本和结构体类型一致。
  • 单个函数的结构名以 “er” 作为后缀,例如 Reader, Writer

五、变量命名规范

  • 变量名称一般遵循驼峰法,首字母根据访问控制原则大写或者小写。
  • 若变量类型为 bool 类型,则名称应以 Has, Is, CanAllow 开头。

六、常量命名规范

  • 常量均需使用全部大写字母组成,并使用下划线分词。
  • 对于枚举类型的常量,需要先创建相应类型。

七、方法注释规范

  • 方法注释应包含方法功能说明、参数说明和返回值说明。

八、import 规范

  • 如果引入了标准库包、程序内部包、第三方包,建议按以下方式组织:
    import (
        "encoding/json"
        "strings"
    
        "myproject/models"
        "myproject/controller"
        "myproject/utils"
    
        "github.com/astaxie/beego"
        "github.com/go-sql-driver/mysql"
    )
    

九、错误处理规范

  • 不能丢弃任何有返回 err 的调用,必须全部处理。
  • 尽早 return:一旦有错误发生,马上返回。
  • 尽量不要使用 panic,除非明确知道在做什么。
  • 错误描述如果是英文必须为小写,不需要标点结尾。
  • 采用独立的错误流进行处理。

十、其他编程规范

  • GO 语言的编程规范强制集成在语言中,明确规定花括号摆放位置。
  • 强制要求一行一句。
  • 不允许导入没有使用的包。
  • 不允许定义没有使用的变量。
  • 提供 gofmt 工具强制格式化代码。

常量

  • 常量是一个简单值的标识符,在程序运行时,不会被修改的量。
  • 常量可以作为枚举,常量组中如不指定类型和初始化值,则与上一行非空常量右值相同。

基础输入输出

  • fmt.Print:用于打印输出内容,不会自动换行。
  • Println:用于打印输出内容,并在结尾添加换行符。
  • Printf:用于格式化输出内容,可以使用占位符指定格式。
  • Sprint:用于将内容格式化为字符串,并返回该字符串。
  • Sprintln:用于将内容格式化为字符串,并在结尾添加换行符,返回该字符串。
  • Sprintf:用于将内容格式化为字符串,可以使用占位符指定格式,返回该字符串。
  • Scan:用于从标准输入中读取数据,并将数据存储到指定的变量中。
  • Scanln:用于从标准输入中读取数据,并将数据存储到指定的变量中,读取到换行符时停止。
  • Scanf:用于从标准输入中按照指定的格式读取数据,并将数据存储到指定的变量中。

示例

package main

import (
    "fmt"
    "os"
    "bufio"
)

func main() {
    fmt.Println("请输入一个字符串:")
    reader := bufio.NewReader(os.Stdin)
    s1, _ := reader.ReadString('\n')
    fmt.Println("读到的数据:", s1)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值