这是我参与「第五届青训营 」伴学笔记创作活动的第 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.Sprintf 或 fmt.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 会随机公平地选出一个执行,其他不会执行。
否则:
-
如果有 default 子句,则执行该语句。
-
如果没有 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语言的其他内容将在下篇笔记进行解释,由于还有很多东西不懂所以对某些概念的描述过于简略
引用
该文章部分内容来自于以下课程或网页:
-
字节内部课:Go 语言上手 - 基础语法
作者:以为有星河
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。