初识GO|青训营笔记

90 阅读8分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

什么是GO语言?

Go 是一门高性能,高并发,语法简单,学习曲线平缓的强类型和静态类型语言,其拥有丰富的标准库,完善的工具链,支持快速编译,跨平台且支持垃圾回收(GC);Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。

对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。

GO语言的结构

声明/引入包/函数/变量/语句&表达式/注释/

简单的代码helloworld

package main

import "fmt"

func main() {

/* 这是我的第一个简单的程序 */

fmt.Println("Hello, World!") }

第一行定义包名,你必须在源文件中非注释的第一行指明这个文件属于哪个包,每个 Go 应用程序都包含一个名为 main 的包

下一行import "fmt"

告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数

不作逐行解释

GO的基础语法

格式化字符串

Go 语言中使用 fmt.Sprintffmt.Printf 格式化字符串并赋值给新串:

  • Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。

  • Printf 根据格式化参数生成格式化的字符串并写入标准输出。

数字类型

布尔型:值只可以是常量 true 或者 false。一个简单的例子:var b bool = true

数字类型:整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。

字符串型

Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。

派生类型

指针类型(Pointer)/数组类型/ 结构化类型(struct)/ 函数类型/Channel 类型/切片类型/接口类型(interface)/ Map 类型

与c语言不同的是多出了Channel 类型/切片类型/接口类型(interface)/ Map 类型。其中切片类型在go语言的应用十分频繁

变量

声明变量的一般形式是使用 var 关键字:

var identifier type

可以一次声明多个变量:

var identifier1, identifier2 type

/未初始化的变量默认为零值,零值就是变量没有做初始化时系统默认设置的值。/

数值类型(包括complex64/128)为 0

布尔类型为 false

字符串为 ""(空字符串)

以下几种类型为 nil

变量声明

指定变量类型*

2.根据值自行判定变量类型

3.如果变量已经使用 var 声明过了,再使用 :=声明变量,就产生编译错误

eg:v_name := value

var intVal int intVal :=1 // 这时候会产生编译错误,因为 intVal 已经声明,不需要重新声明

因为 := 是一个声明语句

多变量声明:类型相同多个变量, 非全局变量

常量

常量的定义格式:

const identifier [type] = value

因为编译器可根据变量的值来推断其类型,故可省略类型说明符[type]

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

运算符

语言运算符大致一致这里就不细说了

条件判断语句

go语言中用if,if...else,if嵌套,switch,select进行条件判断选择

if 7%2 == 0 { fmt.Println("7 is even") } else { fmt.Println("7 is odd") }

if num := 9; num < 0 { fmt,Println(num,"is negative") } else if num < 10 { fmt.Println(num, "has 1 digit") } else { fmt.Println(num, "has mutiple digits") }

我们会注意到在go语言中if语句后的括号是可删去的,不过值得注意的是,if表达式后面的括号是必需的,即使是对于单行语句块,您也必须添加括号,而不能像其他语言那样直接省略。

在switch中:switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough

switch var1 {    case val1:        ...    case val2:        ...    default:        ...}

switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。

switch x.(type){    case type:       statement(s);          case type:       statement(s);     /* 你可以定义任意个数的case */    default: /* 可选 */       statement(s);}
fallthrough

使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。

select语句与switch语句类似:

1.每个 case 都必须是一个通道

2.所有 channel 表达式都会被求值

3.所有被发送的表达式都会被求值

4.如果任意某个通道可以进行,它就执行,其他被忽略。

5.如果有多个 case 都可以运行,select 会随机公平地选出一个执行,其他不会执行。

否则:

  1. 如果有 default 子句,则执行该语句。

  2. 如果没有 default 子句,select 将阻塞,直到某个通道可以运行;Go 不会重新对 channel 或值进行求值

循环语句

在go语言中循环处理语句以for循环,循环嵌套为主;循环控制语句以break语句,continue语句,goto语句为主。

for循环有三种形式

与c语言的for一样:

for init; condition; post { }

和 C 的 while 一样:

for condition { }

和 C 的 for(;;) 一样

for { }

init: 一般为赋值表达式,给控制变量赋初值;

condition: 关系表达式或逻辑表达式,循环控制条件;

post: 一般为赋值表达式,给控制变量增量或减量。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行遍历

函数

Go 语言最少有个 main() 函数。

func function_name( [parameter list] ) [return_types] {   函数体}

func声明/function_name函数名称/parameter list 参数列表/return_types返回类型

默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数

数组

数组格式:var variable_name [SIZE] variable_type

初始化数组中 {} 中的元素个数不能大于 [] 中的数字。

如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小

多维数组如二维数组形如:var arrayName [ x ][ y ] variable_type

在函数定义时,声明形参为数组,我们可以通过以下两种方式来声明:

void myFunction(param [10]int){...}

形参是否设定数组大小均可

指针

C语言的指针我还不会,有点离谱

听说go的简单:

指针声明格式如下:var var_name *var-type

var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。整形和浮点型用iname与fname

不想写代码了,指针的使用在课程中会遇到....

当一个指针被定义后没有分配到任何变量时,它的值为 nil。

nil 指针也称为空指针

nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值

结构体

结构体定义需要使用 type 和 struct 语句。struct 定义一个新的数据类型,结构体中有一个或多个成员。type 设定了结构体的名称。

格式

type struct_variable_type struct {   member definition   member definition   ...   member definition}

初始化

type Employee struct {    ID            int    Name, Address string    DoB           time.Time    Position      string    Salary        int    ManagerID     int}func main(){    fmt.Println(......)}

如果要访问结构体成员,需要使用点号 . 操作符,格式为:结构体**.**成员名

结构体方法看了,不是很懂就不写了

切片(Slice)

在应用中切片的使用更加广泛

声明一个未指定大小的数组来定义切片or使用make()函数进行创建

前者var identifier []type

后者

var slice1 []type = make([]type, len)​也可以简写为​slice1 := make([]type, len)

初始化s:=[]int {6,7,8,9}

len()和cap()

make([]T, length, capacity)

切片是可索引的,并且可以由 len() 方法获取长度。

切片提供了计算容量的方法 cap() 可以测量切片的阈值

空切片即长度为零

我们用copy()和append()函数进行拷贝切片与扩容切片

Map(集合)

可使用内置make函数ormap关键字进行定义:

M := make(map[string]int) 

M := map[string]int{    "XIAOCUI":   18,    "XIAOLI": 19,}

Map中的元素通过key对应的下标语法访问:

M["XIAOLI"] = 19fmt.Println(M["XIAOLI"]) // "19"

使用内置的delete函数可以删除元素:

delete(M, "XIAOLI") // remove element M["XIAOLI"]

GO语言的其他内容将在下篇笔记进行解释,由于还有很多东西不懂所以对某些概念的描述过于简略

引用

该文章部分内容来自于以下课程或网页:

作者:以为有星河 

来源:稀土掘金 

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。