文件名、关键字与标识符
文件名:Go的源文件是以.go为后缀名,文件名可以支持下划线_作为分隔,但是不支持空格或者其他特殊字符
标识符:有效的标识符必须以字符开头(可以使用任何UTF-8编码的字符或者下划线_开头)
有效的标识符:X56,group1,_23,i,өԑ12
无效的标识符:1ab,case,a+b
下划线 _ 作为特殊的标识符,被称为空白标识符,它可以向其他标识符用于变量声明或者赋值,任何赋值给它的值都会被抛弃
关键字或保留字,共有25个:
package/import:导入关键字
inteface:接口定义的关键字
struct:定义抽象数据类型的关键字
type:声明自定义类型的关键字
func:定义函数和方法的关键字
var/const:变量和常量声明的关键字
break/continue/case/for/fallthrough/if/else/switch/goto/default:流程控制关键字
return:函数返回的关键字
select:选择不用类型的通讯的关键字
defer:函数退出之前执行的关键字
go:并行的关键字
map:声明map类型数据的关键字
chan:channel通讯的关键字
range:读取slice、map、channel数据的关键字
预定义标识符,共有36个:
append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int16 uint32
int32 int64 iota len make new nil panic uint64
print println real recover string true uint uint8 uintptr
基本结构和要素
1. 包
包是结构化代码的一种方式,每个程序是由包的概念组成,可以用自身的包或者其他包中导入
package main
每个Go文件都属于且仅属于一个包,一个包可以由很多个.go为扩展名的源文件组成,所以每个文件名和包名一般都不同。
在每次编写源文件的时候,需要在非注释的第一行标明该源文件属于哪个包,如package main。 package main表示一个可独立执行的程序。一个应用程序可以包含不同的包,但有且仅有一个main包。
举个例子:
文件./test/hello.go
package test
import (
"fmt"
)
func init() {
fmt.Println("hello module init function")
}
func Hello() string {
return "hello"
}
文件./test/world.go
package test
import (
“fmt”
)
func init() {
fmt.Println("world module init function")
}
func World() string {
return "world"
}
入口函数main.go
package main
import (
"fmt"
"./test"
)
func main() {
fmt.Println(test.Hello(), test.World())
}
在引入自定义包的时候,需要注意如下几点:
1. 自定义函数中除了init函数之外的自定义函数名,首字母需大写
2. 项目所在位置需要在GOPATH的src路径,否则需要设置包的位置
针对包引入,有如下几个操作:
1) 普通操作,普通导入就是按照加载机制,将要使用的包导入进来
import (
"./test"
)
2) 别名操作,如果连个包名存在冲突,或者包名需要太长需要简写时,可以通过别名导入来解决
import (
test "./test"
)
3) 点操作,.导入可以让包内的方法注册到当前包的上下文中,直接调用方法名即可,不需要加包前缀
import (
. "./test"
)
4) 下划线操作,_是包引用操作,只会执行包下各模块中init方法,并不会导入包,所以无法调用包内的其他方法
import (
_ "./test"
)
包的使用有如下特点:
1) 标准库,Go的安装文件中已经包含了一些可以直接使用的包,即标准库。
2) 如果对一个包进行更改或重新编译,所有引用这个包的客户端程序必须全部重新编译。
Go中的包模型采用了显式以阿里关系的机制来进行快速编译,编译器会从后缀名为.o的对象文件中提取传递依赖类型的信息,举个例子:
如果A.go依赖B.go,而B.go依赖C.go,编译过程如下:
编译C.go -> B.go -> A.go
为了编译A.go,编译器读取的是B.o而不是C.o
3. 每一段代码只会被编译一次。
一个Go程序是通过import关键字将一组包链接在一起。而对于包的引入,有这几种方式:
import "fmt"
import "os"
import "fmt"; import "os"
import (
"fmt"
"os"
)
import ( "fmt"; "os")
包引入的规则:
1) 如果包名不是以 . 或者 / 开头,Go会在全局文件中进行查找
2) 如果包名以./开头,那么Go会在相对目录中查找
3) 如果包名以/开头,那么Go会在绝对路径中查找
4. 可见性规则,包通过这个规则来决定是否将自身的代码对象暴露给外部文件。规则如下:
1) 当标识符以一个大写字母开头,如:Hello,那么使用这种形式的标识符的对象就可以被外部包的代码所使用,这被称作导出(像面向对象语言中的public)
2) 标识符如果以小写字母开头,那么就是对包外是不可见的,只能在包的内部可见并可用(像面向对象语言中的private)
注:大写字母可以使用任何 Unicode 编码的字符,比如希腊文,不仅仅是 ASCII 码中的大写字母
5. 包的分级声明和初始化。在import导入包之后,所定义或声明的常量、变量和类型,这些对象的作用域是在全局的。
全局变量:可以在本包内所有的函数调用。
package main
import "fmt"
var value int
func main () {
value = 10
fmt.Println(value)
}
2. 函数
函数的定义如下:
func functionName() {
}
在functionName()的括号中可以填入0个或者多个函数的参数,通过逗号分隔,每个参数的名称后面必须紧跟参数的类型,例如:
func add(a int , b int ) {
}
main函数,是一个可执行程序所必须包含的函数,一般是程序启动后第一个执行的函数(如果有init()函数会先执行inti函数),main函数没有参数,没有返回类型,如果为main函数添加了参数或者返回类型,会引发构建错误。
程序开始 --> 进行初始化 --> 程序入口main.main() --> 执行main函数中的操作 --> main函数返回 --> 程序结束
一个规范的函数的写法如下:
func functionName(parameter_list) (return_value_list){
...
}
其中,parameter_list表示传入的参数,return_value_list表示返回的参数。函数的第一个字母需小写,如果此函数需要被外部包调用,比如之前写的Hello.go中的Hello()函数,这个时候需要使用大写字母开头,否则就遵循骆驼命名法,第一个单词的首字母小写,其余单词首字母大写。
注释
单行注释,以 // 开头:
import "fmt" // Package implementing formatted I/O
多行注释, 以 /* 开头,以 */ 结尾:
package main
import "fmt"
func main() {
/*
打印
*/
fmt.Println("Hello World!")
}
注:如果需要对函数进行注释,这种称为文档注释,需要以函数名开头进行注释
// Hello ......
func Hello(){}
另外,godoc工具会收集注释并生成一个技术文档
类型
类型定义了某个变量的值的集合与可对其进行操作的集合。
基本类型:int、float、bool、string
结构类型:struct、array、slice、map、channel
只描述类型的行为:interface
结构化的类型没有真正的值,使用nil作为默认值,另外Go语言中不存在类型继承。
通过使用type关键字可以定义自己的类型、也可以定义一个结构体、也可以定义一个已经存在的类型别名:
type IZ int
var a IZ = 5
类型转换
在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值,由于Go语言不存在隐式类型转换,所有的转换必须显式说明,例如:
类型B的值 = 类型B(类型A的值)
a := 5.0
b := int(a)
注:当从一个取值范围较大的转换到取值范围较小的类型时,会发生精度丢失的情况
有疑问加站长微信联系(非本文作者)