Go与C语法比较

Dave Du bio photo By Dave Du

文件结构

C语言:分.h头文件和.c文件,函数声明、宏定义都在头文件里,具体功能实现在.c文件里,对外提供头文件和lib文件,就可以调用模块内的接口。
Go语言:只有.go文件,有了package包的概念,和java、python类似。这样就不需要再include其它文件,只需要import就可以了,编译go文件后生成.a文件。

package test	// 定义包
import "test"	// 引用包,test并不是包,而是路径,GOPATH下的路径

使用一个文件单独运行的程序必须放在package main下面,否则在go run运行时会报错:”go run: cannot run non-main package“,一个可执行文件必须有一个main包,从main包的main函数开始执行。

变量

C语言:定义的类型在前,名字在后,可以指定初始值,如果不指定则不同的编译器的处理是不一样的,往往会有不可以预知的后果。
Go语言:有以下几种形式

var a int // 声明一个int类型的变量,名字在前,类型在后,没有显示初始化时,都初始化为0
var a = 8 // 声明变量的同时赋值,编译器自动推导其数据类型
var a int = 8 // 声明变量的同时赋值
a := 8  // 省略var,用:=声明和初始化,如果变量已经声明过,则只有赋值的作用

结构体

C语言:使用struct定义,然后再用typedef
Go语言:使用type来定义一个新的类型

//定义
type User struct {
        name string
        email string
        password string
    }
//初始化
user = User{name: "liming", email: "liming@gamil.com", password: "pw123456"}
userref = &User{name: "liming", email: "liming@gamil.com", password: "pw123456"}
fmt.Println(user)    //{liming liming@gamil.com pw123456}
fmt.Println(userref) //&{liming liming@gamil.com pw123456}
fmt.Printf("name is %s,  %s", user1.name, userref1.name) //name is liming,  LIMING, 也是使用.来访问成员

函数

C语言:result-list name(parameter-list),返回值只能有一个。
Go语言:func name(parameter-list) (result-list),必须有func关键字,返回值可以有多个,类似lua,首字母大写表明可以被包外调用,小写则不能。

func Split(path string) (dir, file string)

返回值可以定义名字,函数体中可以直接使用,在return前给其赋值就可以了,这样return 后就可以不用接返回值了;调用函数的地方可以在函数体实现的前面。

指针

C语言:指针是C语言里最重要的一个概念,也是最容易出错的地方,运算符就是简单的 & 和 * 一个取地址、一个解析地址。 Go语言:运算符和C语言一样,用法也基本一样,使用new申请内存,数组名不再是地址。

 var outer **int;
 var inter *int;
 inter = new(int);
 *inter = 3;
 outer = &inter;
 //地址一样
 fmt.Println(inter);
 fmt.Println(*outer);
 //值一样
 fmt.Println(*inter);
 fmt.Println(**outer);

注释

C语言:单行用//,多行使用/* */
Go语言:和C一样。

分号

C语言:每个语句后都必须加;结尾。
Go语言:Go语言与C一样都是采用分号来结束一条语句,不一样的是,并不是所有的源码 都要使用分号。Go是采用语法解析器自动在每行末增加分号,所有你在写代码的 时候可以把分号省略。也要注意不要因此多加了一个分号。

布尔类型

C语言:没有专门的布尔类型,0为假,非0即为真。
Go语言:布尔类型的值只有两种:true和false。布尔值并不会隐式转换为数字值0或1,反之亦然。必须使用一个显式的if语句辅助转换:

i := 0
if b {
    i = 1
}

常量

C语言:常量基本都是使用宏来定义 Go语言:没有宏的概念,而是引入了类似C++中的const,常量表达式的值在编译期计算,而不是在运行期,可以批量声明多个常量。

const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

iota 常量生成器,类似于C语言中的枚举类型

type Weekday int

const (
    Sunday Weekday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)

控制语句

  • if
  • for
  • switch

内存