Go语言基础
Go语言介绍
Go语言简介
Go语言是谷歌2009发布的第二款开源编程语言。
Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。
Go语言主要特征
1、可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了。
2、静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,写起来的效率很高。
3、语言层面支持并发,这个就是Go语言最大的特色,可以充分的利用多核,很容易的使用并发。
4、内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说GC不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC。
5、简单易学,Go语言的作者都有C的基因,那么Go自然而然就有了C的基因,那么Go关键字是25个,但是表达能力很强大,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等。
丰富的标准库,Go目前已经内置了大量的库,特别是网络库非常强大。
6、内置强大的工具,Go语言里面内置了很多工具链,最好的应该是gofmt工具,自动化格式化代码,能够让团队review变得如此的简单,代码格式一模一样,想不一样都很困难。
跨平台编译,如果你写的Go代码不包含cgo,那么就可以做到window系统编译linux的应用,如何做到的呢?Go引用了plan9的代码,这就是不依赖系统的信息。
7、内嵌C语言支持,前面说了作者是C语言的作者,所以Go语言里面也可以直接包含C语言代码,利用现有的丰富的C语言库。
Go语言标准命令解释
假如你已安装了Go语言环境,你可以在命令行执行go命令查看相关的Go语言命令:
Go is a tool for managing Go source code.
Usage:
go command [arguments]
The commands are:
build compile packages and dependencies
clean remove object files
doc show documentation for package or symbol
env print Go environment information
bug start a bug report
fix run go tool fix on packages
fmt run gofmt on package sources
generate generate Go files by processing source
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages
run compile and run Go program
test test packages
tool run specified go tool
version print Go version
vet run go tool vet on packages
Use “go help [command]” for more information about a command.
Additional help topics:
c calling between Go and C
buildmode description of build modes
filetype file types
gopath GOPATH environment variable
environment environment variables
importpath import path syntax
packages description of package lists
testflag description of testing flags
testfunc description of testing functions
Use “go help [topic]” for more information about that topic.
go env 用于打印Go语言的环境信息。
go run 命令可以编译并运行命令源码文件。
go get 可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并对它们进行编译和安装。
go build 命令用于编译我们指定的源码文件或代码包以及它们的依赖包。
go install 用于编译并安装指定的代码包及它们的依赖包。
go clean 命令会删除掉执行其它命令时产生的一些文件和目录。
go doc 命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。
go test 命令用于对Go语言编写的程序进行测试。
go list 命令的作用是列出指定的代码包的信息。
go fix 会把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。
go vet 是一个用于检查Go语言源码中静态错误的简单工具。
go tool pprof 命令来交互式的访问概要文件的内容。
Go语言命名
Go****语言关键字
1、Go语言有25个关键字:
2、关键字用途:
var :用于变量的声明
const :用于常量的声明
type :用于声明类型
func :用于声明函数和方法
package :用于声明包文件
import :用于导入其它package
return :用于从函数返回
defer :延迟调用,在函数退出之前执行
go :创建一个协程
select :用于选择不同类型的通讯
interface :用于定义接口
struct :用于定义数据类型
break、case、continue、for、fallthrough、else、if、switch、goto、default :用于流程控制
chan :用于声明chan类型数据
map :用于声明map类型数据
range :用于遍历array、slice、map、channel数据
Go****语言保留字
Go语言有37个保留字:
Go****语言命名规范
Go语言的包(package)、变量、常量、自定义类型、函数、方法的命名方式遵循以下规则:
1)首字符可以是任意的Unicode字符或者下划线
2)剩余字符可以是Unicode字符、下划线、数字
3)字符长度不限
4)不要使用Go语言的关键字和保留字命名
Go语言内置类型和函数
内置类型
内置函数
Go 语言拥有一些不需要进行导入操作就可以使用的内置函数。它们有时可以针对不同的类型进行操作,例如:len、cap 和 append,或必须用于系统级的操作,例如:panic。因此,它们需要直接获得编译器的支持。
内置接口error
只要实现了Error()函数,返回值为String的就实现了error接口。
type error interface {
Error() String
}
Go语言特殊函数介绍
**main**
函数
Go语言程序的默认入口函数(主函数):func main()
函数体用{}一对括号包裹。
只能应用于package main
func main(){
//函数体
}
**init**
函数
go语言中init
函数用于包package
的初始化,该函数是go语言的一个重要特性。
init函数有下面的特征:
1、init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
2、每个包可以拥有多个init函数
3、包的每个源文件也可以拥有多个init函数
4、同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
5、不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
6、init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
**init**
函数和**main**
函数的异同
相同点:
两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。
不同点:
init函数可以应用于任意包中,且可以重复定义多个。
main函数只能用于main包中,且只能定义一个。
两个函数的执行顺序
对同一个go文件的init()
调用顺序是从上到下的。
对同一个package
中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()
函数。
对于不同的package
,如果不相互依赖的话,按照main包中"先import的后调用"的顺序调用其包中的init()
,如果package
存在依赖,则先调用最早被依赖的package
中的init()
,最后调用main函数。
如果init函数中使用了println()
或者print()
你会发现在执行过程中这两个不会按照你想象中的顺序执行。这两个函数官方只推荐在测试环境中使用,对于正式环境不要使用。
Go语言运算符
运算符用于在程序运行时执行数学或逻辑运算。
Go 语言内置的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符。
算术运算符
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
++ | 自增 |
– | 自减 |
关系运算符
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 |
逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。 |
! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 |
位运算符
运算符 | 描述 |
---|---|
& | 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 |
| | 按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或。 |
^ | 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 |
<< | 左移运算符"<<“是双目运算符。左移n位就是乘以2的n次方。 其功能把”<<“左边的运算数的各二进位全部左移若干位,由”<<"右边的数指定移动的位数,高位丢弃,低位补0。 |
>> | 右移运算符">>“是双目运算符。右移n位就是除以2的n次方。 其功能是把”>>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数。 |
赋值运算符
运算符 | 描述 |
---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
<<= | 左移后赋值 |
>>= | 右移后赋值 |
&= | 按位与后赋值 |
^= | 按位异或后赋值 |
|= | 按位或后赋值 |
其他运算符
运算符 | 描述 |
---|---|
& | 取地址符,返回变量存储地址 |
* | 取值符,返回指针的变量 |
运算符优先级
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:
优先级 | 运算符 |
---|---|
7 | ^ ! |
6 | * / % << >> & &^ |
5 | + - | ^ |
4 | == != < <= >= > |
3 | <- |
2 | && |
1 | || |
特殊标识符
“_”是特殊标识符,又称占位符(空标识符号),用来忽略结果。
1、特殊标识符应用在import中
在Go语言里,import的作用是导入其他package。
特殊标识符(如:import _ oldboy/golang)的作用:当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import _ 引用该包。即使用(import _ 包路径)只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。
示例:
代码目录结构
src
|
±-- main.go
|
±-- oldboy
|
±-- oldboy.go
main.go
package main
import _ “./oldboy”
func main() {
// oldboy.Print()
//编译报错:./main.go:6:5: undefined: oldboy
}
oldboy.go
package oldboy
import “fmt”
func init() {
fmt.Println(“The old boy welcomes you.”)
}
func Print() {
fmt.Println(“Hello!”)
}
运行结果:
The old boy welcomes you.
2、特殊标识符应用在代码中
package main
func main() {
str, _ := oldboy()
_ = str
}
func oldboy() (str string, err error) {
str = “The old boy welcomes you.”
err = nil
return
}
解释:
占位符,意思是那个位置本应赋给某个值,但是咱们不需要这个值。所以就把该值赋给占位符,意思是丢掉不要。这样编译器可以更好的优化,任何类型的单个值都可以丢给占位符。
第一个占位符:这种情况是忽略函数返回值,函数返回两个结果,而你只想要一个结果。
第二个占位符:这种情况是忽略未使用的局部变量,如果声明的局部变量,不使用,编译器是会报错。