文章目录
- 前置篇
- 显式
- 组合
- 大纲
前置篇
显式
在 C 语言中,下面这段代码可以正常编译并输出正确结果:
#include <stdio.h>
int main() {
short int a = 5;
int b = 8;
long c = 0;
c = a + b;
printf("%ld\n", c);
}
我们看到在上面这段代码中,变量 a、b 和 c 的类型均不相同,C 语言编译器在编译c =
a + b这一行时,会自动将短整型变量 a 和整型变量 b,先转换为 long 类型然后相加,
并将所得结果存储在 long 类型变量 c 中。那如果换成 Go 来实现这个计算会怎么样呢?我
们先把上面的 C 程序转化成等价的 Go 代码:
package main
import "fmt"
func main() {
var a int16 = 5
var b int = 8
var c int64
c = a + b
fmt.Printf("%d\n", c)
}
如果我们编译这段程序,将得到类似这样的编译器错误:“invalid operation: a + b
(mismatched types int16 and int)”。我们能看到 Go 与 C 语言的隐式自动类型转换不
同,Go 不允许不同类型的整型变量进行混合计算,它同样也不会对其进行隐式的自动转
换。
因此,如果要使这段代码通过编译,我们就需要对变量 a 和 b 进行显式转型,就像下面代
码段中这样:
c = int64(a) + int64(b)
fmt.Printf("%d\n", c)
在 Go 语言中,不同类型变量是不能在一起进行混合计算的,这是因为 Go 希望开发人员
明确知道自己在做什么,这与 C 语言的“信任程序员”原则完全不同,因此你需要以显式
的方式通过转型统一参与计算各个变量的类型。
除此之外,Go 设计者所崇尚的显式哲学还直接决定了 Go 语言错误处理的形态:Go 语言
采用了显式的基于值比较的错误处理方案,函数 / 方法中的错误都会通过 return 语句显式
地返回,并且通常调用者不能忽略对返回的错误的处理
组合
Go 语言为支撑组合的设计提供了类型嵌入(Type Embedding)。通过类型嵌入,我们可
以将已经实现的功能嵌入到新类型中,以快速满足新类型的功能需求,这种方式有些类似
经典面向对象语言中的“继承”机制,但在原理上却与面向对象中的继承完全不同,这是
一种 Go 设计者们精心设计的“语法糖”。
// $GOROOT/src/sync/pool.go
type poolLocal struct {
private interface{}
shared []interface{}
Mutex
pad [128]byte
}
在代码段中,我们在 poolLocal 这个结构体类型中嵌入了类型 Mutex,这就使得
poolLocal 这个类型具有了互斥同步的能力,我们可以通过 poolLocal 类型的变量,直接
调用 Mutex 类型的方法 Lock 或 Unlock。
注意:
go中type struct{}和type interface{}区别