Go语言的创作与C语言有很大的关系。比如它的首席作者就是肯-汤普逊(Ken Thompson),他与丹尼斯-里奇一道研发了Unix系统,后又协助丹尼斯-里奇创作了C语言。他参与Go语言的设计就避免不了受C语言的影响。
不过,今天我想和大家逐条分享我感受到的Go语言的简洁之处。
定义变量
var 变量名 类型
varaint32定义并赋值,让类型自动推断:
vara=100使用”:=“语法,还可以更精简:
a:=100”:=“语法的规则,”:=“左侧的所有变量中至少有一个变量在该代码段中是第一次出现的,如:
varnum1,num2=100,200num1,num2,num3:=500,600,700注意:”:=“不能用于常量定义
常量定义
const 常量名 类型
constaint32=100或通过赋值,自动推断类型
consta=100枚举
const (
枚举值1
枚举值2
枚举值3
…
)
const(login=0logout=1exit=2loading=3fetch=4)这里每个枚举值的赋值都不能省略,否则它们的值都是一样的,这样毫无意义。这一点比其他高级语言来说有点差,别的都不需要这样做,C语言默认就是从0开始,后而就依次叠加。Go语言提供了iota来代替这个赋值。
const(login=iotalogout exit loading fetch)iota是从0开始,并且自动增长。iota是在=作用域结束后增长的。举个例子:
const(login=iotalogout exit=iota+1loading=iota+3)login = 0
logout = 1
exit = 3
loading=6
分支与循环语句
if 条件1 {
// 逻辑1
} else if 条件2 {
// 逻辑2
} else {
// 逻辑3
}
这里的简洁体现在if条件上,因为Go的作者们认为if后肯定是一个条件的表达式,所以小括号没有什么特别用,即使用写了,在运行时,也会在编译前删除掉。
循环只有一个for,它做完了所有do while,while,for等在C语言里的循环方式。
在C语言中的for循环方式,在Go里这样被表达的:
fori:=1;i<=5;i++{println(i)}在C语言中的do while循环方式,在Go里这样被表达的:
j:=0for{println(j)j++ifj>=5{break}}在C语言中的while循环方式,在Go里这样被表达的:
j:=0forj<5{println(j)j++}函数
func 函数名(参数列表) 返回值类型列表 {
// 函数体
}
Go函数可以有0到多个返回值。
funcsum(aint32,bint32)int32{returna+b}为了简洁,如果邻近的参数类型相同,可以用一个类型修饰多个参数:
funcsum(a,bint32)int32{returna+b}在这里顺便引入一下指针,在Go语言里的指针不像C语言里的指针,在Go语言里,指针只有间接引用的作用。举个交换两个变量的值的例子:
funcmain(){a,b:=1,2swap(a,b)println(a,b)}funcswap(a,bint){tmp:=a a=b b=tmp}a,b的值在swap里被交换了, 但是结果没有影响main函数里的a,b,因为swap是使用值传递的方式把a,b的值传递过来。如果是传递引用就可以解决这个问题,这个时候指针就派上用场了:
funcmain(){a,b:=1,2swap(&a,&b)println(a,b)}funcswap(a,b*int){tmp:=*a*a=*b*b=tmp}因为Go函数可以返回多个值,因此还可以利用此特性来交换两个变量的值:
funcmain(){a,b:=1,2n,m:=swap(a,b)println(n,m)}funcswap(a,bint)(int,int){returnb,a}不具名的函数就是函数闭包:
funcmain(){a,b:=1,2n,m:=func(num1,num2int)(int,int){returnnum2,num1}(a,b)println(n,m)}在闭包里可以读取父函数的变量:
funcmain(){f:=parent()println(f())println(f())println(f())}funcparent()func()int{i:=0returnfunc()int{i++returni}}parent()函数返回一个闭包(匿名函数),它里面引用了父函数的变量i。运行上面的代码,你会发现i在自增,一直没有被释放。i变量是不会被释放的,因为它被闭包一直引用着,所以当parent()函数调用完后,i没有被释放。
在Go语言里,函数是第一等公民,可以当作参数传递:
funcmain(){a,b:=1,2addOrSub(a,b,add)println(addOrSub(a,b,add))println(addOrSub(a,b,sub))}funcadd(a,bint)int{returna+b}funcsub(a,bint)int{returna-b}funcaddOrSub(a,bint,ffunc(int,int)int)int{returnf(a,b)}Map的遍历
其实我个人挺不喜欢Java的map遍历的,而Go语言的Map遍历真的很简洁,同时构建Map却有些麻烦,它必须通过make函数来构建:
mmap:=make(map[string]string)mmap["China"]="BeiJing"mmap["France"]="Paris"mmap["US"]="Washington.D.C"fork,v:=rangemmap{fmt.Println(k,v)}使用range关键字来遍历Map。