前面的话
Go 语言是类C语言,C语言在逻辑上是完全信任程序员,而Go在这之上省去了很多程序员浪费开发时间的繁琐步骤。思想上就是 Less can be more 让事情变得复杂很容易,让事情变得简单才难。
基础语法
包声明
.go 文件的第一行就是包的声明,每个文件夹下只能有一个包名。
package helloworld
其中比较特别的是 main 包。在一个正常程序中,只有 main 包能运行。
包导入
Go 语言通过 import 关键字导入其他的包。主要有四种导入格式:
import (
"fmt"
myfmt "fmt"
_ "fmt"
. "fmt"
)
- 第一种就是正常导入,以
fmt为包名使用该包下的可导出函数、常量。 - 第二种是别名形式,以
myfmt为包名使用该包下的可导出函数、常量。 - 第三种表示不使用该包,而仅仅让该函数的
init方法运行一下,并不显示的使用该包的其他内容。常在一些driver包中见到。(因为Go语言中不允许未使用的变量、导入包存在) - 第四种直接将该包下的函数导入当前包中,如
fmt.Printf可以直接用Printf调用。
常用变量类型
-
布尔: 值类型,
bool值域只有true和false,默认值为false。- 可以通过基本的逻辑运算符
&& || ! == !=进行运算与赋值。
- 可以通过基本的逻辑运算符
-
整型: 值类型,
int8/uint8(byte)int16/uint16int32(rune)/uint32intint64/uint64,按字节数大小递增,只能赋予整数/正整数类型,默认值为0。- 常用整型为
byte与int,byte用于表示字符,而int字节数大小不确定,具体大小是跟机器的 CPU 位数相关的。如果 CPU 是 32 位的,那么 int 就占 4 字节,如果 CPU 是 64 位的,那么 int 就占 8 字节。
- 常用整型为
-
浮点数: 值类型,
float32float64能赋予整数和浮点数,但精度较低。默认值为0.0,通常使用float64。 -
字符串: 值类型,
string,声明后字符串本身不可修改,但变量可重新赋值,默认值为空字符串""。 -
结构体: 值类型
struct,需自己定义。所有空结构体只占用Go程序中的一个空间。 -
数组: 值类型,带有
[ArraySize]进行声明的基本类型,ArraySize是常量,不可拓展。 -
切片: 引用类型,带有
[]进行声明的基本类型,可拓展。一般来说通常用切片替代数组,默认值为nil。 -
哈希: 引用类型,
map[T]V以T类型为键,V类型为值,默认值为nil。 -
通道: 引用类型,带有
chan进行声明的类型,默认值为nil。 -
接口: 接口类型,
interface,默认值为nil。Go语言中所有类型都算实现了空接口interface{},因此任何值都可以赋给interface{}类型的变量。 -
函数: 函数类型,默认值为
nil,具体类型根据函数签名确定。 -
值类型在函数调用时会被拷贝,即使修改也不会影响原变量,而引用类型在函数调用时会影响到原变量。
-
接口类型在传参时如果表示的是值类型,不影响原变量,如果表示引用类型,会影响原变量
-
函数本身如果是闭包的,该闭包值会被影响
变量声明
var name string
name := ""
变量声明有两种方法:
var关键字声明。- 可以在函数体外使用
- 主动声明类型
:=运算符直接赋值。- 无法在函数体外使用
Go语言自动进行类型推断,可以直接接收函数返回值- 能在一些控制语句中临时定义变量
- 运算符左侧至少要有一个未声明过的变量
- 运算符右侧是数值常量时,默认使用
int和float64为变量类型
流程控制
ifelseswitch进行一次分支判断for进行循环breakcontinue控制循环
for 关键字支持三种格式
for init ; condation ; body_next {body}逻辑上运行顺序为init -> condation -> body -> body_next -> condation -> body -> ... -> !condationinit只执行一次,可以进行赋值和短变量声明condation运行结果必须为布尔类型,每次循环开启前都会进行一次判断- 在
body中执行continue语句会直接跳转到body_next,执行break语句会直接中断循环 body_next只能是简单的赋值语句
for condation {body}简化代码,简去了init和body_next的执行for {}死循环代码,直到运行break语句才跳出循环
函数定义
Go 语言的函数有以下特点:
- 无需声明原型。
- 支持不定变参。
- 支持多返回值。
- 支持返回参数的命名。
- 支持匿名函数和闭包。
- 函数也是一种类型,一个函数可以赋值给相同签名的变量。
函数的声明主要由函数名,参数列表,返回值列表和函数体组成。
func main() {
ok := HelloWorld("fff", "lmx", "jhm")
fmt.Println(ok)
}
func HelloWorld(name string, otherNames ...string) (helloOK bool) {
fmt.Printf("Hello %s and %v\n", name, otherNames)
return true
}
// output: Hello fff and [lmx jhm]
// output: true
func是函数声明HelloWorld是函数名(name string, otherNames ...string)是参数列表otherNames接收其他的不定变参,将其组成一个切片slice。
(helloOK bool)是返回值列表{}内的是函数体
其中参数列表和返回值列表都是可以省略的,可以化简化为如下等签名形式(参数声明后一定要被使用,或用占位符 _ 替换该参数名):