国庆节七天假期,这段时间刚好项目那边催的不是很紧,基本上每天都是白天重构一下项目代码,晚上自己学习。(大概是因为容总那边的人都去度假了把项目进度放慢了吧。这两天“彩虹”姐姐也来凑热闹,据说还是直接从澳门出发,然后漂洋过海到了咱们大广东,昨天还在顺德发了个大脾气。苦逼的咱们几个还是天天待在工作室发霉,因为害怕被彩虹姐姐带走,所以把工作室的门窗锁得紧紧的,然后把空调开到20多度,穿上外套,哈哈,这才叫个爽啊!)。最近看到了一篇文章名曰《不要在一门技术上吊死》 深有感触,于是就开始着手学习久闻大名但又与Web开发毫无相干的Go语言。至于什么是Go语言,它有哪些特点,度娘一下一大堆,所以,我这里就不做详细的介绍了,直接从语法开始了。因为,我也是0基础开始接触Go语言,所以难免会有很多错误或者不妥的地方,所以,大家发现了的就留个言让我纠正一下啦,毕竟写博客是为了一起学习,共同进步嘛。好吧,废话不多说了,现在直接进入正题吧!
至于Go的环境是如何搭建起来的呢,这里也不说啦,网上教程也有很多。不过呢,go的编译环境需要FQ下载的,我这里有个安装包放在了百度云盘了go1.5.1.windows-amd64安装包 直接点击下载就行了哈。go的官网golang.com好像也是被封杀了的,不FQ是看不到的,我这里有个中文版的golang学习网址,有需要的可以进去看看中文版golang好吧,下面真正开始走进Go的神奇王国啦!
首先我们来看看Go语言的变量是如何声明的。学过C或者C++语言的都知道,变量声明是使用“变量类型”+“变量标识符”组成的,比如:int a; 就是在声明一个为整型的变量了。Go语言的变量声明方式与C和C++语言有明显的不同。对于纯粹的变量声明,Go语言引入了关键字var(学过javascript的这时候肯定会很兴奋哦,因为javascript也是酱紫声明的嘛,先别激动,看了后面就会知道了,二者还是有好的的区别呢)。
var v1 int // 整型 var v2 string // 字符串 var v3 [10]int // 数组 var v4 []int // 数组切片 var v5 struct { // 结构体 f int } var v6 *int // 指针 var v7 map[string]int // map,key为string类型,value为int类型 var v8 func(a int) int // 函数
通过上面的例子,我们可以看到而“变量类型”是放在最后的。这跟我们的javascript是不同的,由于javascript是一们弱语言,不需要说明变量的类型的。综合上面的例子,我们知道了Go的变量声明语法如下:
var “变量名” “变量类型”
有一点需要提醒的是,我们发现上面例子中,Go语言的每个语句后面都没有分号。Go是没有要求在每个语句结束位置夹分号的。如果你吃饱了撑着,也是可以加的,编译也是可以通过的。这点事跟C或者C++不一样的,C/C++不加分号是不可以通过编译的。
var关键字的另一种用法是可以将若干个需要声明的变量放置在一起,免得程序员需要重复写var关键字,如下所示:
var ( v1 int v2 string )
这有点儿像javascript里面的"单var模式"声明变量呢!
下面再来看看怎样初始化变量吧!
对于声明变量时需要进行初始化的场景,var关键字可以保留,但不再是必要的元素,如下所示:
var v1 int = 10 // 正确的使用方式1 var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型 v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型
以 上三种用法的效果是完全一样的。与第一种用法相比,第三种用法需要输入的字符数大大减少,是懒程序员和聪明程序员的最佳选择。这里Go语言也引入了另一个 C和C++中没有的符号(冒号和等号的组合:=),用于明确表达同时进行变量声明和初始化的工作。指定类型已不再是必需的,Go编译器可以从初始化表达式 的右值推导出该变量应该声明为哪种类型,这让Go语言看起来有点像动态类型语言,尽管Go语言实际上是不折不扣的强类型语言(静态类型语言)。当然,出现 在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误,比如下面这个写法:
var i int i := 2
会导致类似如下的编译错误:
no new variables on left side of :=
我们已经知道了变量的声明和初始化了,下面再来看看常量这个东西吧。javascript是没有常量的,但是C/C++就有,其实,Go的常量定义和C是相像的,都是通过const关键字。请看下面的例子:
const Pi float64 = 3.14159265358979323846 const zero = 0.0 // 无类型浮点常量 const ( size int64 = 1024 eof = -1 // 无类型整型常量 ) const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值 const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", 无类型整型和字符串常量
Go的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它与字面常量一样,是无类型常量。常量定义的右值也可以是一个在编译期运算的常量表达式,比如
const mask = 1 << 3
由于常量的赋值是一个编译期行为,所以右值不能出现任何需要运行期才能得出结果的表达式,比如试图以如下方式定义常量就会导致编译错误:
const Home = os.GetEnv("HOME")
原因很简单,os.GetEnv()只有在运行期才能知道返回结果,在编译期并不能确定,所以无法作为常量定义的右值。
上面已经介绍了变量和常量的声明了,下面我们来Go的函数声明了
所有Go函数(包括在对象编程中会提到的类型成员函数)以关键字func开头。一个常规的函数定义包含以下部分:
func 函数名(参数列表)(返回值列表) { // 函数体 } //对应的一个实例如下: func Compute(value1 int, value2 float64)(result float64, err error) { // 函数体 }
通过上面例子,我们会发现,Go的函数可以有多个返回值的。这是与C/C++不同之处。以上的示例函数Compute()返回了两个值,一个叫result,另一个是err。并不是所有返回值都必须赋值。在函数返回时没有被明确赋值的返回值都会被设置为默认值,比如result会被设为0.0,err会被设为nil。
为了让别人读懂自己的代码,也为了自己在若干年后看的懂之前写的代码,注释是程序设计必不可少的。Go程序的代码注释与C++保持一致,即同时支持以下两种用法:
/* 块注释 */ // 行注释
接下来,看看Go对花括号(特别是左花括号"{")的位置的一些限制吧。我们在C/C++或者javascript中,左花括号可以写在一行末尾,也可以另起一行写在开头。但是,如果使用Go语言,左花括号"{"另起一行放置,这样做会使Go编译器报告编译错误,这点需要特别注意。比如有如下代码,我们把左花括号写在了另一行的开头,则会报错
//对应的一个实例如下: func Compute(value1 int, value2 float64)(result float64, err error) { // 函数体 }
报错内容如下:
syntax error: unexpected semicolon or newline before {
正确的写法应该把函数的左花括号放在第一行的末尾,如下:
//对应的一个实例如下: func Compute(value1 int, value2 float64)(result float64, err error) { // 函数体 }
最后,我们一起看看Go有哪些数据类型吧,这里仅是简单的列出了Go数据类型,具体的使用方法下次再一起讨论。
Go语言内置以下这些基础类型:
? 布尔类型:bool。
? 整型:int8、byte、int16、int、uint、uintptr等。
? 浮点类型:float32、float64。
? 复数类型:complex64、complex128。
? 字符串:string。
? 字符类型:rune。
? 错误类型:error。
此外,Go语言也支持以下这些复合类型:
? 指针(pointer)
? 数组(array)
? 切片(slice)
? 字典(map)
? 通道(chan)
? 结构体(struct)
? 接口(interface)