Go 相比 Java 的优势
- 简洁性:Go 语言的语法简洁,代码量少,易于维护。
- 并发性:原生支持 goroutine 和 channel,便于实现并发编程。
- 高效性:Go 编译速度快,运行性能接近 C++。
- 内存管理:内置垃圾回收机制,减少了手动内存管理的复杂性。
类型声明
- 使用
var声明类型,例如var e float64 - 使用
:=自动推导类型,例如f := float32(e) const常量声明时会自动确定类型
为什么要类型后置
Go 采用类型后置,使代码更接近自然语言阅读顺序,有助于理解函数签名和变量声明的含义。
在《Go's Declaration Syntax》里,Rob Pike 解释了为什么 Go 语言的声明语法采用类型后置的设计,而非像 C 语言那样的类型前置语法。这个设计不仅让 Go 的语法更加直观,而且在处理复杂类型声明时具有明显优势。
C 语言的声明方式
在 C 中,声明语法通过模拟表达式来描述类型。这种方法对简单的类型有效,但对于复杂的类型,特别是指向函数的指针,阅读起来会变得非常困难。
例如,在 C 中定义一个指向函数的指针,我们会写成:
int (*fp)(int a, int b);
上面的声明表示 fp 是一个指向返回 int 类型、接受两个 int 参数的函数的指针。这个声明规则要求开发者从内向外阅读类型,这会使得复杂的类型声明变得不直观,特别是当返回值或参数中包含其他函数指针时。例如:
int (*(*fp)(int (*)(int, int), int))(int, int);
这样的声明非常复杂且难以阅读,令人难以直接理解 fp 的类型。
Go 语言的声明方式
使用 Go 的语法,前面的 C 例子可以更清晰地表达为:
var fp func(func(int, int) int, int) func(int, int) int
在 Go 中,我们可以直接从左到右阅读,理解 fp 的类型:fp 是一个函数,它接受一个返回 int 类型的函数(参数是两个 int),以及另一个 int 作为参数,返回的也是一个接受两个 int 并返回 int 的函数。通过这种语法,代码的意图变得更加清晰,阅读更加流畅。
控制语句
- if-else 支持简洁的赋值和条件判断,例如
if num := 9; num < 0 - for 循环:
for {}表示死循环,Go 没有while,用for来代替。 - 函数返回值:Go 函数可以返回两个值,第一个是正常的返回值,第二个是错误值。
- switch-case:
switch语句不需要加括号。- 每个
case分支不需要break,默认自动终止。 - 推荐使用
switch-case替代多个if-else。 - 支持多种类型,包括结构体等。
结构体创建
- 使用
type和struct关键字定义结构体,例如:type Person struct { Name string Age int } - 创建实例时可以使用字段名初始化:
p := Person{Name: "Alice", Age: 30}
字符串操作
- 使用
strings包进行字符串操作,例如strings.Contains()检查字符串是否包含子串。 - 使用
%v格式化输出任意结构体,用%+v输出字段名,用%#v输出详细内容。
JSON 操作
- 导入
"encoding/json"包进行 JSON 序列化和反序列化。 - 序列化:
buf = json.Marshal(a),a是结构体。buf需要强制转换成string才能打印。 - 反序列化:
json.Unmarshal(buf, &b),b是结构体的指针。
数字解析
- 使用
strconv包处理字符串到数字的转换:strconv.ParseInt(字符串, 进制(整数), 位数(64/32))strconv.ParseFloat(字符串, 精度(64/32))