这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
Go语言简介
- 高性能,高并发
- 语法简单
- 标准库丰富
- 工具链完善
- 静态链接(最终的项目是一个exe文件,不会动态链接其它文件)
- 快速编译
- 跨平台
- 垃圾回收
一个简单的Hello World程序
package main
import(
"fmt"
)
func main(){
fmt.Println("Hello World")
}
开发环境
到官网(The Go Programming Language)安装Go语言环境
可以选择VSCode(需要安装Go插件)或Goland
这是一个云开发环境:Gitpod: Always ready to code.
基础语法
1、控制台运行编译Go程序
比如有一个hello.go文件
- 编译:go build hello.go 生成hello.exe可执行文件
- 直接运行:go run hello.go
2、变量声明
//直接声明,由程序自动判断变量类型
var t = true
var a = "hello world"
//显示指明变量类型
var b,c int = 1,2
//声明但不初始化(默认值为0)
var e float64
//一个简写方式
f:=float32(e) //声明了一个变量f,并赋值float32(e)
//字符串属于基本类型,可以用加号拼接,const表示s是一个常量
const s string = "hello"
3、分支语句(if else)
package main
import "fmt"
func main(){
//if后边直接加语句,不需要加圆括号
//与 *if* 匹配的左括号 *{* 必须与if和表达式放在同一行,
//如果尝试将“{”放在其他位置,将会触发编译错误。
//同理,与else匹配的“{”也必须与else在同一行,
//else也必须与上一个if或else if的右边的大括号在一行。
if 7%2==0 {
fmt.Println("7是偶数")
} else {
fmt.Println("7是奇数")
}
//除了以上语法要求外,Go语言的if语句还有这样一种特殊写法:
if zt:=getStatus();zt!=0 {
fmt.Println(zt)
return
}
/*这里假设getStatus()是一个带有返回值的函数,zt:=getStatus()是一个语句,
执行getStatus()后,将函数返回值保存到zt变量中。zt!=0才是if的判断表达式,
当zt不等于0时,打印变量并返回。这种写法可以将返回值与判断放在一行进行处理,
而且返回值的作用范围被限制在if、else语句组合中*/
}
4、分支语句(switch)
package main
import "fmt"
func main(){
a:=2
//Go中的switch不需要显示的为每个case添加break语句,执行完某个case会自动跳出switch
//如果想实现执行某个case后继续往下一个case执行,需要添加falllthrough关键字
switch a {
case 1:
fmt.Println(1)
case 2:
fmt.Println(2)
fallthrough
case 3:
fmt.Println(3)
default:
fmt.Println("other")
}
//switch还可以这么用(比使用if-else要方便很多)
switch {
case false:
fmt.Println("1、case 条件语句为 false")
fallthrough
case true:
fmt.Println("2、case 条件语句为 true")
fallthrough
case false:
fmt.Println("3、case 条件语句为 false")
fallthrough
case true:
fmt.Println("4、case 条件语句为 true")
case false:
fmt.Println("5、case 条件语句为 false")
fallthrough
default:
fmt.Println("6、默认 case")
}
}
5、循环语句
Go语言中没有while循环,只有for关键字 ,可以使用break,continue关键字
package main
import "fmt"
fuunc main(){
i:=1
//相当于while循环
for i<=3 {
fmt.Println(i)
i = i+1;
}
//死循环
for{
fmt.Println("loop")
}
//经典的for循环
for j:=1;j<10;j++{
fmt.Println(j)
}
}
6、数组
package main
import "fmt"
fuunc main(){
var a [5]int
a[4] = 100
fmt.Println(a[4],len(a)) //100 5
b:=[5]int{1,2,3,4,5}
fmt.Println(b)//[1,2,3,4,5]
var c [2][3]int //一个俩行三列的数组
}
由于数组长度是固定的,所以实际用的更多的是切片
7、切片
切片相比数组,操作更加丰富且长度可变
package main
import "fmt"
fuunc main(){
//创建一个长度为3的切片
s := make([]string,3)
s[0] = "Hello"
s[1] = "World"
s[2] = "!!!"
//获取切片或数组的长度
fmt.Println(len(s))
//在末尾追加元素(一定要把append的返回值赋值给原切片)
s = append(s,"asd")
s = append(s,"qwe","ert") //追加俩个元素
//复制一个切片
c := make([]string,len(s))
copy(c,s)
//类似于python的切片操作(索引不可以是负数)
fmt.Println(s[2:5]) //["!!!","asd","qwe"]
fmt.Println(s[:5]) //["Hello","World","!!!","asd","qwe"]
fmt.Println(s[2:]) //["!!!","asd","qwe","ert"]
//直接初始化
good := []string{"g","o","o","d"}
}
8、map
package main
import "fmt"
fuunc main(){
//创建map
m := make(map[string]int)
s["one"] = 1
m["two"] = 2
fmt.Println(m) //map[one:1 two:2]
fmt.Println(len(m)) //2
fmt.Println(m["one"]) //1
//m中不存在“three”,返回int的默认值0
fmt.Println(m["three"]) //0
//判断一个元素是否存在
r,ok :=m["three"]
fmt.Println(r,ok) //0 false
//删除一个元素
delete(m,"one")
m2 :=map[string]int{"one":1,"two":2}
}
map内部是无序的,遍历的时候也是随机顺序
9、range
package main
import "fmt"
fuunc main(){
nums := []int{1,2,3}
//遍历数组(i是下标,num是对应的值)
for i,num:= range nums{
fmt.Println(i,num)
}
m := map[string]string{"a":"A","b":"B"}
//遍历map
for k,v:= range m {
fmt.Println(k,v)
}
}
10、指针
和C语言指针用法一致
11、函数
package main
import "fmt"
//返回值类型写在最后边
func add(a int,b int) int{
return a+b
}
//函数可以返回多个值
func exists(m map[string]string, k string) (v string,ok bool){
v,ok = m[k]
return v,ok
}
fuunc main(){
res := add(1,2)
fmt.Println(res) //3
v,ok := exists(map[string]string{"a":A},"a")
fmt.Println(v,ok) // A True