【go的变量声明的设计思想与下划线使用】关于 go 语法的一些碎碎念

关于 go 语法的一些碎碎念

Table of Contents

go 语言变量声明

go 语言与 c 语言类似,以面向数据的设计为主,通过一个个的函数组织代码,大多数的语法也和 c 相似。但是,go 与 c 的对比也有较多的不同。其中最明显的一点就是 go 语言声明变量将变量的类型放在了变量名称的后面。尤其在函数的使用中,两者的表达的清晰程度明显有所区别。下面给出了相关代码的对比,在对应的代码块中,前者为 c 语言,后者为 go 语言。

  • 基本语法的对比:

    int x;
    int *p;
    int a[3];
    int f(int, int);
    
    var x int
    var p *int
    var a [3]int
    func f(int, int) int
    

    在简单的变量、函数声明面前,二者并不能体现出明显差别。

  • 函数指针的对比

    int (*fp)(int, int);
    // 去除函数名的形式
    // int (*)(int, int);
    // 容易与下面的函数声明混淆
    // int *(int, int);
    
    var fp func(int, int) int
    // 去除函数名的形式
    // var func(int, int) int
    

    可以看到在 c 语言中,由于函数指针需要与函数区分开,所以引入了 * 作为指针来区分两者。由于指针具有多种含义,可以是函数指针,也可以是变量指针,且在 c 中函数指针与函数返回值紧紧靠在一起。函数指针的 * 容易与返回值混淆造成混乱。

    而 go 语言恰好对 c 语言的声明作了相应的改进,淡化了指针的概念,使用 func 代表函数指针,且进行了函数指针和返回值的分离。因此,go 与 c 语言相比,看起来更加清晰。

  • 对于更复杂的情况:如函数指针的指向的函数的参数包含函数指针,函数指针指向的函数的返回值是函数指针等,还有其它更加复杂的情况。

    int (*(*fp)(int (*)(int, int), int))(int, int);
    
    var fp func(int, int) func(func(int, int) int, int) int
    

    上面两个代码块的函数指针声明等效,都指向一个参数列表为两个 int、返回值为函数指针的函数。该函数指针(返回值)指向的是返回值是 int,参数列表为函数指针和 int 的函数。参数列表的函数指针指向的函数为返回值为 int、参数列表为两个 int 的函数。

    面对上述如此复杂的函数指针声明,go 语言显然处理得比 c 语言合适。c 语言中由于返回值是一个函数指针,出现了令人难以接受的 (*(*fp)) 表示方式。而 go 语言的声明显然层次性更好。

go 语言选择将类型名放在变量名之后,解决了 c 语言处理函数指针声明所遇到的难题。将函数指针声明的各个部分划分清楚。

而且,在阅读 go 源代码的时候更符合我们的习惯,能够第一眼看到变量的名称。先阅读变量名,能让我们快速把握代码的意思,而不必纠结于变量的类型等其它信息,更符合自顶向下的思想。

下划线的使用

go 语言的代码中,有时候会用到下划线 _ 作为变量名。例如,官方的 go 安装教程中有这样的一段测试代码:

package stringutil

import "testing"

func TestReverse(t *testing.T) {
    cases := []struct {
        in, want string
    }{
        {"Hello, world", "dlrow ,olleH"},
        {"Hello, 世界", "界世 ,olleH"},
        {"", ""},
    }
    for _, c := range cases {
        got := Reverse(c.in)
        if got != c.want {
            t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
        }
    }
}

此时,range 的第一个返回值是数据的索引,第二个返回值是数据的值,即为对应的 case。显然,在测试中我们只关心 cases 中的每一个样例 case,对索引我们不感兴趣。因此,我们使用了占位符 _,忽略这个变量。同时,使用 _ 还可以告诉编译器,让其进行相应的优化,提高代码运行速度。另外,go 语言的编译器不允许代码中出现未使用的变量。如果不使用占位符 _,出现了不使用的变量名,编译器会报错无法成功编译。

补充:有时候在 import 语句中,使用了下划线表示不将完整的包导入到代码中,而仅仅是调用了 init() 函数,此时无法调用包中的其它函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值