Golang语法设计选择探讨

Golang语法设计选择探讨 我是Go语言的新手,很好奇为什么Go语言偏离了典型的语法,比如在变量名前声明变量类型,或者在函数名后指定返回类型。引入关键字var有什么好处?语言设计者为什么更喜欢var my_var int而不是int my_var,这背后有什么背景吗?

6 回复

这对我来说是最大的问题,一年前我开始学习Go时就是这样。我曾认为Go的创建者是邪恶的,只是想惹恼所有人。现在我已经习惯了,不再抱怨了。但当你用几种不同的语言编程时,其中一种语言在这方面与众不同,这确实很烦人。抱歉,不过我没有答案给你……

更多关于Golang语法设计选择探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


微笑 谢谢!考虑到 Rob Pike 和 Ken Thompson 都有 C 语言背景,并且看到这门语言是如何构建以简化 C 语言的内存管理,我对这个选择感到好奇。另一个我觉得有趣的地方是函数可以返回多个值。如果一个函数返回两个值,它真的还是一个函数吗?

类似地,我对Go语法的一个不满之处是type关键字。我不明白为什么他们不能直接去掉它,让我们直接用Go中仅有的两种类型的确切名称作为前缀:struct和interface,例如:

type Blah struct { }
type Bleh interface { }

应该只是:

struct Blah { }
interface Blah { }

……然后他们就可以把type保留给真正创建类型别名的情况,例如:

type SomeTypeAlias int;

为struct和interface去掉type关键字,可以使代码更易读,在编写时更符合认知逻辑,并且更简洁。

我的观点是,Go语言的创造者们看到了C语言的做法,并认为那是错误的,需要改变。

在C语言中,定义一个包含4个函数指针的数组是这样写的:

int (*p[4]) (int x, int y);

而在Go语言中,它看起来是这样的:

var p [4]func(x int, y int) int

我认为Go语言的写法更容易阅读……从左到右看,它表示定义一个变量 var,名为 p,它是一个大小为4的数组 [4],其中的每个元素都是一个函数指针 func,该函数接受一个名为 x 的参数,类型为 int,以及一个名为 y 的参数,类型也是 int,并且该函数返回一个 int

而理解C语言风格的声明意味着什么则是一件费脑筋的事情,它需要从内部的 p 开始,然后向外推导。这里有一篇关于如何阅读C语言风格类型定义的文章。

所有这些都是由反向声明引起的!

Go语言在语法设计上确实与C、Java等语言有所不同,这种设计选择主要基于可读性、简洁性和工具链支持等方面的考虑。

类型后置的语法优势

// Go的风格 - 类型后置
var count int
func process(data []byte) (result string, err error)

// 对比C风格 - 类型前置
int count;
string process(byte[] data)

类型后置让代码从左到右阅读更自然,特别是在复杂类型声明时:

// 复杂类型声明更清晰
var handler func(string) (int, error)
var m map[string][]int

var关键字的作用

// var允许批量声明和初始化分离
var (
    x int
    y string
    z = 42  // 类型推断
)

// 对比短变量声明
x := 10  // 只能在函数内使用

设计背景

  • Rob Pike和Ken Thompson等设计者从C语言的经验出发,希望减少语法歧义
  • 类型后置配合类型推断,让代码在保持静态类型安全的同时更简洁
  • 这种设计让函数签名更清晰,特别是多返回值时:
func ReadFile(name string) ([]byte, error)

实际使用中的便利性

// 类型推断减少冗余
var i = 10          // 推断为int
var s = "hello"     // 推断为string
var f = 3.14        // 推断为float64

// 与结构体配合
type Config struct {
    Timeout time.Duration
}
var cfg Config

这种语法设计经过多年实践,在大型代码库中表现出良好的可维护性,IDE和工具链也能更好地支持代码分析和重构。

回到顶部