一、前言
为了尽可能获得最佳的运行性能,Go语言被设计成一门静态编译型的语言,而不是动态解释型的。Go语言的编译速度非常快,明显的要快过其他同类语言,比如C和C++。
Go语言的官方编译器被称为gc。
Go语言具有以下几个特点:
- 快速编译
- 并发设计易于实现
- 高效的垃圾回收机制
二、Go程序结构
Go程序是以包(package)的形式来组织的,这和Python语言类似。Go程序一般由三部分组成:包声明部分、第三方包导入部分和函数声明部分。
- Go语言使用关键字“package"声明要创建的包;
- 使用关键字“import"导入第三方包;
- 使用关键词“func”声明要创建的函数。
1、本地包声明
包是组成Go程序的基本单位,所以每个Go程序源代码的开始都是一个包声明(Package Declaration),格式如下:
package < pkgName >
包声明的关键字是“package",pkgName告诉编译器当前文件属于哪个包。当要生成
一个可执行的Go程序时,必须建立一个名为main的包,并且在该包中应包含一个名为
main的函数,main函数是Go程序运行时的人口。
除了main包之外,其他名称的包里不能包含main函数,且编译后都会生成*.a文件(也就是包文件),并被自动存放在pkg文件夹中。需要注意的是,一个可执行程序,有且仅有一个main包,一个main包有且仅有一个main函数。
2、第三方包导入
在包声明之后,如果需要调用Go标准库函数(这些标准库函数通常封装在第三方包中),还要使用关键字“import”导人第三方包,这就是包的导入(Package Import),但必须是非main包。在Go语言中,包的导入有三种模式:正常模式、别名模式和简便模式。
(1)正常模式
在正常模式中,第三方包导入格式如下:
import < pkgName >
import是包声明关键字,pkgName告诉编译器要导入哪个包。包导入之后,就可以使用下面的语句格式对包中的函数或类型进行调用:
< pkgName >. < funcName >
本例要调用fmt包的Println方法输出信息,所以调用语句为:
fmt. Println( .. )
(2)别名模式
在别名模式中,当要使用第三方包时,包名可能会非常接近或者相同,
此时就可以使用别名来进行区别和调用,导入格式如下:
import 别名 < pkgName >
(3)简便模式
在简便模式中,可以直接使用funcName进行第三方包的调用,不需要pkgName,导入格式如下:
import . < pkgName >
简便模式和别名模式同时使用时容易混淆,不建议使用。import语句在其他编程语言中都有类似的概念,比如在C中,“包"的概念被称为“库”,调用时使用include语句包含到C程序中。
需要注意的是,如果导入一个包之后,源程序并未调用包里的函数或类型,则编译时会报错。这其实是Go语言实现快速编译的一种机制,Go在编译源文件之前,编译器会对所有导入的包进行检查,看它是否和源文件之间有关联,如果没有关联就是没用的,则不允许导入。这样可以保障源代码体积是最小的,也可以加快编译速度。
3、函数声明
和其他高级程序设计语言一样(比如C语言),Go程序的真正执行体也是函数,所以每个Go程序至少应声明一个main函数。函数声明以关键字func开头,格式如下:
func funcName(参数列表)(返回值列表){
//函数体
}
与其他函数不同,Go程序中的main函数既没有参数,也没有返回值。如果在命令行中要向main传入参数,可在os. Args变量中保存。另外,Go函数还支持多返回值,在后面的章节中介绍。
三、Go程序语言要点
示例代码:helloworld.go
package main
import (
"fmt"
)
func main() {
fmt.Printf("Hello World! 你好,世界!")
}
- 1、Go语句中的分号
通过helloworld. go还可以看到Go程序语句里没有分号。其实,和C语言一样,Go语言的正式语法也使用分号来终止语句。和C语言不同的是,这些分号由词法分析器在扫描源代码过程中使用简单的规则自动插入,因此输入源代码多数时候就不需要分号了。Go程序中,出现分号的典型位置是在for循环的分隔语句或类似之处。
- 2、左大括号的约定
Go语言规定,函数、控制结构(if、for、switch或select)等的左大括号“{”,“必须和函数声明或控制结构放在同一行”。如果将左大括号“放在函数声明,控制语句的下一行”,编译器会在左大括号的前方自动插人一个分号,这可能导致异常的结果。
- 3、Go语言对UTF-8的支持
最后可以看到输出的内容里面包含中文“你好,世界!”,实际上,Go是天生支持UTF-8的,任何字符都可以直接输出,甚至可以用UTF-8中的任何字符作为标识符,这是因为UTF-8的发明者也就是Go的发明者,所以它天生就具有多语言的支持。
- 4、可见性规则
Go语言中,使用大小写来决定常量、变量、类型、接口、结构或函数是否可以被外部包所调用,根据约定:
(1)函数名首字母小写,即为private。
(2)函数名首字母大写,即为public。
四、Go的注释方式
在Go程序代码中添加注释,是为了让代码阅读起来更容易理解,良好的编码习惯其中就包括为代码加上清晰明确的注释说明。Go程序的注释方式有两种:单行注释和块注释。
1、单行注释
单行注释以“//”开始,一般对单行语句的含义进行说明,可以单独放在一行,也可以跟在代码后,和代码放在同一行。下面是单行注释的例子。
//每个main包有且仅有一个main函数
func main() {
fmt. Println("Hello World!你好,世界!") //函数Println()用于行输出
}
2、块注释
块注释以“/ *”开始,以“* /”结束,经常用于对一个函数或语句块进行说明。下面是注释的例子。
/*
描述:函数main()是一个可执行包的人口函数
参数:无
返回值:无
*/
func main() {
fmt. Println("Hello World!你好,世界!")
}
3、使用注释限制代码执行
注释的一般作用是为代码添加阅读说明,但有时也可以使用注释限制某些语句的执行,使编译器不去处理它。尤其在调试程序的时候非常有用。例如:
func main() {
t: = time.Now() //时间戳
//fmt. Println(t)
/*
fmt. Println(t.String()) //年月日时分秒
fmt. Println(t.Format("2006year 01month 02day")) //年月日
*/
fmt. Println(t.Weekday().String()) //星期几
}
五、Go语言关键字及标识符
Go标识符是一个非空的字母或数字串,其中第一个字符必须是字母,该标识符也不能是关键字的名字。字母可以是一个下划线,或者Unicode编码分类中的任何字符,如大写字母“Lu”(letter,uppercase)、 小写字母“Ll" (letter, lowercase)、 首字母大写“Lt" (letter, titlecase)、修饰符字母“Lm”(letter, modifier)或者其他字母,“Lo”(etter, other)。 这些字符包含所有的英文字母(A~Z以及a~z)。数字则是Unicode编码"Nd"分类(number, decimal digit)中的任何字符,这些字符包括阿拉伯数字0~9。编译器不允许使用与某个关键字(见表2-1)一样的名字作为标识符。
标识符都是区分大小写的,因此LINECOUNT、Linecount、 LineCount、 lineCount和
linecount是5个不一样的标识符。以大写字母开头的标识符,即Unicode分类中属于“Lu”的字母(包含A~Z),是公开的——以 Go语言的术语来说就是导出的,而任何其他的标识符都是私有的——用 Go语言的术语来说就是未导出的。(这项规则不适用于包的名字,包名约定为全小写。)
空标识符“_”是一个占位符,它用于在赋值操作的时候将某个值赋值给空标识符,从而达到丢弃该值的目的。空标识符不是一个新的变量,因此将它用于:=操作符的时候,必须同时为至少另一个值赋值。通过将函数的某个甚至是所有返回值赋值给空标识符的形式将其丢弃是合法的。然而,如果不需要得到函数的任何返回值,更为方便的做法是简单地忽略它。这里有些例子: