前言
最近看完了两本golang的书,也使用golang搭建了一个框架,写了一个物联网项目
所以来做个入门总结
关键字
golang 一共有25个关键字 ,不能用作标识符,分成三大类,程序包管理、实体声明和定义、流程控制
如果有其它语言基础,大部分都可以知道其功能
程序包管理:
package
package用于声明包的名称,需放在go文件所有代码的最前面。一个包由一个或多个go源文件组成,需放在同一个目录下,且同一个目录下的这些go文件的package的名字只能有一个
import 包引入
其中包路径前面可以有三中修饰符中的某一个 [ _ . alias ]
package <packagename>
import _ "package path"
import . "package path"
import alias "package path"
import (
_ "package path"
. "package path"
alias "package path"
)
实体声明和定义
var
定义变量
var name T //name默认为类型T的零值
var name = value //根据值value推断变量name的类型
var name T = value //赋初始值时指明类型
var name1, name2 T //同时定义多个同类型变量
//同时定义多个不同类型的变量
var (
name string ="dable"
age int = 18
)
//最简单用法,也是最常用法
name := value
const 常量
同 var
func 函数和方法
func 用于定义函数,Go函数支持变参且返回值支持多个。
func funcName(){} //无参无返回值
func funcName(t T) T {} //有参有返回值
func funcName(t T, list ...T) (T1,T1) {} //有变参有多个返回值
func (s struct) funcName() {} //可以带结构体
type 类型
type 用于定义类型,比如定义struct、interface等类型
struct 结构体
struct 用于定义结构体
type Name struct {
X, Y int
}
interface 接口
interface 用于定义接口。一个接口是一个方法集,如果一个类型实现了一个接口中的所有方法集,那么说明该类型实现此接口。接口类型变量可以存储任何实现了该接口的类型的值。特别的,interface{}表示空接口类型,默认地,所有类型均实现了空接口,所以interface{}可以接收任意类型值。
//空接口
interface{}
//Person接口
type Person interface {
Walk()
Run()
Say(s string)
}
map 字典
map 用于声明映射变量。映射属容器类类型,是一个同种类型元素的无序组,通过唯一的键可以获取对应的值。可以使用 make 创建 map 变量,未初始化的映射值为 nil。创建map变量主要有如下几种方式:
//创建0容量的map
var map1 = make(map[T1] T2)
//创建指定容量的map,只是初始容量,会自动扩容
var map2 = make(map[T]T2, 10)
//创建并初始化map
var map3 = map[string]int {
"k1" : 1,
"k2" : 2,
}
// 创建可以放任意值的map
var map4 = make(map[string]interface{})
chan 管道
chan用于声明channel(信道)。信道提供一种机制使两个并发执行的函数实现同步,并通过传递具体元素类型的值来通信。未初始化的信道值为 nil。声明格式如下:
//定义chan类型变量
var ch chan int = make(chan int, 10);
//或者
ch := make(chan int, 10);
//给chan写数据
ch <- 1;
ch <- 2;
//从chan 读数据
var x int;
x = <-ch;
其中<-操作符指定信道的方向,发送或接收。若没有给定方向,那么该信道就是双向的。信道可通过类型转换或赋值被强制为只发送或只接收。
信道的初始化可以通过 make 函数来实现,其结果值充当了对底层数据结构的引用。初始化时可以为信道设置缓冲区大小,默认值是零,表示不带缓冲的或同步的信道
ci := make(chan int) // 整数类型的无缓冲信道
cj := make(chan int, 0) // 整数类型的无缓冲信道
cp := make(chan *os.File, 100) // 指向文件指针的带缓冲信道
流程控制
go 多线程
go用于创建Go线程(goroutine),实现并发编程。Go程是与其它Go程并发运行在同一地址空间的函数,相比于线程与进程,它是轻量级的。Go程在多线程操作系统上可实现多路复用,因此若一个线程阻塞,比如说等待I/O,那么其它的线程就会运行。Go程的设计隐藏了线程创建和管理的诸多复杂性。
在函数或方法前添加 go 关键字能够在新的Go程中调用它。当调用完成后,该Go程也会安静地退出。效果有点像Unix Shell中的 & 符号,它能让命令在后台运行。
//并发执行
go func()
select
select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行
Go 编程语言中 select 语句的语法如下:
select {
case communication clause :
statement(s);
case communication clause :
statement(s);
/* 你可以定义任意数量的 case */
default : /* 可选 */
statement(s);
}
for 循环
for是Go中唯一用于循环结构的关键词。有三个使用方式,分别是单个循环条件,经典的初始化/条件/后续形式,还有和range关键词结合使用来遍历容器类对象(数组、切片、映射)。
//单条件
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}
//初始化/条件/后续形式
//注意Go中没有前置自增与自减运算符,即++i是非法的
for i:=0; i < 3; i++ {
fmt.Println(i)
}
//for range形式遍历数组
array :=[...]int{0,1,2,3,4,5}
for i, v :=range array{
fmt.Println(i,v)
}
range 迭代器
同 for 一起使用,遍历对象↑
break
break用于终止最内层的"for"、“switch"或"select"语句的执行。
continue
结合for一起使用,continue通常用于结束当前循环
if else
条件判断语句
- 可省略条件表达式的括号;
- 支持初始化语句,可定义代码块局部变量;
- if与else块中只有一条语句也需要添加大括号;
- 起始大括号必须与if与else同行。
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else{
/* 在布尔表达式为 false 时执行 */
}
//支持多个else if
if 表达式1 {
// 符合表达式1执行
} else if 表达式2 {
// 符合表达式2 执行
} else {
// 没有符合的表达式执行
}
// 可以声明变量
if bool := true;bool {
//执行
}
switch case default fallthrough
这四个关键字是结合使用的,switch语句提供多路执行,表达式或类型说明符与switch中的case相比较从而决定执行哪一分支。default用于给出默认分支,即所有的case分支都不满足时执行default分支。Go中的switch语句在执行完某个case子句后,不会再顺序地执行后面的case子句,而是结束当前switch语句。使用fallthrough可以继续执行后面的case与default子句。
//表达式选择
switch tag {
default: s3() //default子句可以出现在switch语句中的任意位置,不一定是最后一个
case 0, 1, 2, 3: s1() //case表达式可以提供多个待匹配的值,使用逗号分隔
case 4, 5, 6, 7: s2()
}
switch x := f(); {
case x < 0: return -x //case表达式无需为常量
default: return x
}
switch { //缺失的switch表达式意为"true"
case x < y: f1()
fallthrough //强制执行下一个case子句
case x < z: f2()
//此处没有fallthrough,switch执行流在此终止
case x == 4: f3()
}
//类型选择
switch i := x.(type) {
case int:
printInt(i) // i 的类型为 int
case float64:
printFloat64(i) // i 的类型为 float64
case func(int) float64:
printFunction(i) // i 的类型为 func(int) float64
case bool, string:
printString("type is bool or string") // i 的类型为 bool or string
default:
printString("don't know the type") // i 的类型未知
}
defer
defer语句用于预设一个函数调用,即推迟函数的执行。 该函数会在执行 defer 的函数返回之前立即执行。它显得非比寻常, 但却是处理一些事情的有效方式,例如无论以何种路径返回,都必须释放资源的函数。 典型的例子就是解锁互斥和关闭文件。如果有多个defer 按照倒序执行。
//将文件的内容作为字符串返回。
func Contents(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close() // f.Close 会在函数结束后运行
var result []byte
buf := make([]byte, 100)
for {
n, err := f.Read(buf[0:])
result = append(result, buf[0:n]...)
if err != nil {
if err == io.EOF {
break
}
return "", err // 我们在这里返回后,f 就会被关闭
}
}
return string(result), nil // 我们在这里返回后,f 就会被关闭
}
goto
goto用于将程序的执行转移到与其标签相应的语句。可以使用goto退出多层"for"、“switch"或"select”,功能类似于break携带标签。
//终止for
L:
for i < n {
n++
goto L
}
return
return用于函数执行的终止并可选地提供一个或多个返回值。 任何在函数F中被推迟的函数会在F 返回给其调用者前执行。函数可以通过return返回多个值。如果返回值在函数返回形参中指定了名字,那么return时可不带返回值列表。
//无返回值
func noResult() {
return
}
//单返回值
func f1() int {
return 2
}
//多返回值
func f2() (float64, float64) {
re = 7.0
im = 4.0
return re, im
}
//返回值已具名
unc f3() (re float64, im float64) {
re = 7.0
im = 4.0
return
}
参考:
网友评论