golang基础
golang特点
- 高性能、高并发
- 语法简单、学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
Hello World
代码如下
在控制台中通过go run xxx.go直接运行
也可以通过go build xxx.go编译为二进制文件,然后通过./xxx运行
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
变量(var)
golang变量名由字母、数字、下划线组成,其中首个字符不能为数字
golang声明变量时一般使用 var 关键字
变量声明格式:var 变量名 类型
变量批量声明:var (变量名 类型...)
变量声明并初始化格式:var 变量名 类型 = value
常用方式:变量名 :=值(通过:=声明变量可以自动根据值的内容判断类型)
注:初始化时var可以根据值来判断类型,因此使用var时类型可省略
package main
import "fmt"
var (
name string
age int
sex bool
) //变量批量声明
func main() {
var a int //变量声明
var b,c int = 1,2
d :=3
}
常量(const)
常量是一个简单值的标识符,在程序运行时,不会被修改的量
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型
常量声明格式:const 变量名 类型 = value
批量声明:const 变量名1,变量名2 = value1,value2
注意:const初始化时类型同样可以省略
package main
import "fmt"
func main() {
const a int = 1
const b =2
const c,d = 3,4
}
iota
iota是go语言的常量计数器,只能在常量的表达式中使用
iota在const关键字出现时将被重置为0,const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
语言解释可能有点不明所以,看代码就知道它是什么东西了
const(
a = iota //值为0 ,iota为0
b //值为1 ,iota为1
c //值为2 ,iota为2
d = "CYY" //值为CYY ,iota为3
e //值为CYY ,iota为4
f = 100 //值为100 ,iota为5
g //值为100 ,iota为6
h = iota //值为7 ,iota为7
i //值为8 ,iota为8
)
if else
- 可省略条件表达式括号
{不可独立一行,必须在条件表达式后面- 持初始化语句,可定义代码块局部变量
package main
import "fmt"
func main() {
// 定义一个代码块局部变量x,并进行初始化
if x := 10; x > 0 {
fmt.Println(x) // 输出:10
}
// x只在if语句块中有效,此处无法访问x
}
for
在golang中只有for循环,没有while循环
while循环的操作可以通过for循环来实现
for循环条件表达式括号也可省略
for循环有3种方式:
for init; condition; post { }
for condition { } //while循环的实现
for { } //死循环
//init: 一般为赋值表达式,给控制变量赋初值
//condition: 关系表达式或逻辑表达式,循环控制条件
//post: 一般为赋值表达式,给控制变量增量或减量
数组
数组定义:var 变量名 [size]int
- 数组长度是数组类型的一部分,因此
var arr1 [10] int和var arr2 [20] int的类型是不同的 - 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:
len(arr)-1 - 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值
- 数组长度不确定,可以使用
...代替数组的长度,编译器会自动推断数组长度 - 初始化时变量名后的类型可省略
package main
import "fmt"
func main() {
var arr1 [5]int = [5]int{1,2,3,4,5}
var arr2 = [5]int{1,2,3,4,5}
var arr3 = [...]int{1,2,3,4,5,6,7}
a :=[5]int{1,2,3} //未初始化元素为0
b :=[...]int{}
c :=[5]int{2:1,4:2} //通过下标初始化,c[2]=1,c[4]=2
}
Slice(切片)
slice是一种可变长度的数组,也就是我们的动态数组
是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递
声明一个未指定大小的数组来定义切片:var slice []int
使用make()函数创建切片:slice :=make([]type,len,capacity)
len为数组长度,可扩充
capacity为数组容量,表示数组的最大容量,是一个可选参数
len不能大于capacity
package main
import "fmt"
func main() {
arr :=[5]int{1,2,3,4,5}
var slice1 []int //定义切片,为空切片,默认为nil,长度为0
slice2 :=make([]int,10) //长度为10的切片,容量为len*2
slice3 :=arr[:] //数组转为切片
slice4 :=arr[1,3] //取arr[1]到arr[3]的元素创建切片
}
len()函数:换取切片长度cap()函数:获取切片容量append()函数:向切片添加元素copy()函数:拷贝切片,用于扩充容量
map
定义格式:map :=make(map[keytype]valuetype,initialCapacity)
initialCapacity可省略
获取键值:value :=map[key]或value,ok :=map[key]
ok值是判断键是否存在,存在ok值为true,不存在则为false,value值为对应类型的默认值
package main
import "fmt"
func main() {
map1 :=make(map[string]int,10) //容量为10的空map
map2 :=make(map[string]int){
"num1": 1,
"num2": 2,
"num3": 3,
}
value , ok :=map2["num1"] //获取键值
map2["num1"] = 100 //修改键值
delete(map2,"num2") //删除键值对
}
range
golang的range类似迭代器操作,返回 (索引, 值) 或 (键, 值)
package main
import "fmt"
func main() {
map :=make(map[string]int){"num":1,}
for key, value := range map {
newMap[key] = value
}
arr :=[]int{1,2,3,4,5}
for _, value := range arr { //不需要的值可以通过`_`忽略
fmt.Println(value)
}
}
函数
- 无需声明原型
- 支持不定 变参
- 支持多返回值
- 支持命名返回参数。
- 支持匿名函数和闭包
- 函数也是一种类型,一个函数可以赋值给变量
- 不支持 嵌套 (nested) 一个包不能有两个名字一样的函数
- 不支持 重载 (overload)
- 不支持 默认参数 (default parameter)
函数定义
func function_name( [parameter list] ) [return_types] { //
函数体
}
package main
import "fmt"
func add(a,b int) (sum int ,c int ,d int){
c,d =a,b
return a+b,c,d
}
func main() {
add(1,2)
}
指针
golang中的函数传参都是值拷贝
当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量
传递数据使用指针,而无须拷贝数据
类型指针不能进行偏移和运算
golang中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)
package main
import "fmt"
func main() {
a :=100
b :=&a
fmt.Printf("a:%d ptr:%p\n", a, &a) // a:100 ptr:0xc00001a078
fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
fmt.Println(&b) // 0xc00000e018
}
结构体
golang中可以使用type关键字来定义自定义类型
声明格式
type 结构体名 struct{
结构体变量名 变量类型
结构体变量名 变量类型
...
}
实例化
package main
import "fmt"
type student struct{
Name string
Age int
homeAddress string
}
func main() {
student1 :=student{Name: "CYY",Age: 20,homeAddress :"掘金总部"}
student2 :=student{"stu",18,"掘金分部"}
str := student1.Name
fmt.Println(str)
}
外部包访问: 结构体大写时可被外部包访问,结构体成员变量首字母为小写时,成员变量视为私有,不可在外部包被访问,首字母为大写时可被外部包访问
Go语言开发注意事项
- Go源文件以
go为拓展名 - Go应用程序的执行入口是
main()函数 - Go语言严格区分大小写
- Go语言每个语句后不需要
;(Go语言会在每行后自动加上) - Go编译器是一行行进行编译的,因此一行只有一条语句,不能把多条语句写在同一行,否则会报错
- Go语言定义的变量或import的报如果未使用,代码不能编译通过
- 大括号是成对出现的
Go官方编程指南
API文档查询:pkg.go.dev/std
Golang 中文网 API文档:studygolang.com/pkgdoc
结言
欢迎各位大佬在评论区指出文章的错误,共同交流学习
总结的可能有点简陋,笔记部分内容参考www.topgoer.com