1.命名规范
任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。
当命名(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:SetupRouter,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出。
命名如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的。
- 结构体命名
采用驼峰命名法,首字母根据访问控制大写或者小写
- 变量命名
和结构体类似,变量名称一般遵循驼峰法,首字母根据访问控制原则大写或者小写,但遇到特有名词时,需要遵循以下规则:
如果变量为私有,且特有名词为首个单词,则使用小写,如 appService;
若变量类型为 bool 类型,则名称应以 Has, Is, Can 或 Allow 开头。
var isExist bool
var hasConflict bool
var canManage bool
2.常量
// "const" 关键字用来定义常量
const s string = "appropriate"
3.变量
变量的声明的语法:
var 变量名字 类型 = 表达式
“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量
简短声明变量:
名字 := 表达式
destination := 12
result := rand.Float64() * 3.0
3.赋值
将要被赋值的变量放在=的左边,新值的表达 式放在=的右边
x = 6 // 命令变量的赋值
*p = true // 通过指针间接赋值
person.name = "aa" // 结构体字段赋值
count[n] = count[n] * scale // 数组、slice或map的元素赋值
4.整型
有符号整形数类型:
int8,长度:1字节, 取值范围:(-128 ~ 127)
int16,长度:2字节,取值范围:(-32768 ~ 32767)
int32,长度:4字节,取值范围:(-2,147,483,648 ~ 2,147,483,647)
int64.长度:8字节,取值范围:(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)
无符号整形数类型:
uint8,长度:1字节, 取值范围:(0 ~ 255)
uint16,长度:2字节,取值范围:(0 ~ 65535)
uint32,长度:4字节,取值范围:(0 ~ 4,294,967,295)
uint64.长度:8字节,取值范围:(0 ~ 18,446,744,073,709,551,615)
5.数组
var m [3]int = [3]int{1, 2, 3}
var n [3]int = [3]int{1, 2}
fmt.Println(n[2]) // "0"
如果在数组的长度位置出现的是“…”省略号,则表示数组的长度是根据初始化值的个数来计算
var m [3]int = [3]int{1, 2, 3}
var n [3]int = [3]int{1, 2}
fmt.Println(n[2]) // "0"
数组可以直接进行比较,当数组内的元素都一样的时候表示两个数组相等
arr1 := [3]int{1, 2, 3}
arr2 := [3]int{1, 2, 3}
arr3 := [3]int{1, 2, 4}
fmt.Println(arr1 == arr2, arr1 == arr3) //true,false
数组可以作为函数的参数传入 ,如果想要改变就只能使用指针
func ArrIsArgs(arr *[4]int) {
arr[0] = 20
}
m:= [...]int{1, 2, 3, 4}
ArrIsArgs(&m)
- & 是取地址符号 , 即取得某个变量的地址 ,如: &a
- 是指针运算符 , 可以表示一个变量是指针类型 , 也可以表示指针变量所指向的存储单元 , 也就是这个地址所存储的值.
6.slice
一个Slice由三部分组成:指向数组的指针,长度和容量。内置的len和cap函数可以分别返回slice的长度和容量
- 下标方式创建slice
func newSlice() []int {
arr := [3]int{1, 2, 3}
slice := arr[0:1]
return slice
}
使用下标初始化切片不会复制原数组或原切片的数据,而只会创建一个指向原数组的切片结构体,所以修改新切片的数据也会修改原切片
- 可以用内置函数make创建切片,:
func make([]T, len, cap) []T
var s []byte
s = make([]byte, 5, 5)
// s == []byte{0, 0, 0, 0, 0}
len(s) == 5
cap(s) == 5
s = s[low : high : max]
切片的三个参数的切片截取的意义为 low 为截取的起始下标(含), high 为窃取的结束下标(不含 high),max 为切片保留的原切片的最大下标(不含 max);即新切片从老切片的 low 下标元素开始,len = high - low, cap = max - low;
截取的规则是左闭右开
package main
import "fmt"
func main(){
s := []int {0, 1, 2, 3, 4, 5, 6,7, 8, 9}
s = s[1:9:10]
fmt.Println(s)
fmt.Println(len(s))
fmt.Println(cap(s))
}
//[1 2 3 4 5 6 7 8]
//8
//9
slice扩容
var s []int
s = append(s, 1)
fmt.Println(len(s), cap(s)) //1 1
s = append(s, 2)
fmt.Println(len(s), cap(s)) //2 2
s = append(s, 3)
fmt.Println(len(s), cap(s)) //3 4
s = append(s, 4)
fmt.Println(len(s), cap(s)) //4 4
s = append(s, 5)
fmt.Println(len(s), cap(s)) //5 8
s的初始值为nil,s并没有绑定任何数组。使用append函数后开始绑定底层数组,但是每增加一个元素,如果底层数组容量不够,数组的容量都会按照变化,而且每次都是原数组长度的2倍。
7.打印变量
- “%v\n” 如果值是一个结构体,%+v 的格式化输出内容将包括结构体的字段名
- “%T\n” 需要打印值的类型,使用 %T
- “%t\n” 格式化布尔值
- “%d\n” 十进制格式化``
- “%b\n” 输出二进制
- “%c\n” 输出给定整数的对应字符
- “%f\n” 浮点型
- “%s\n” 字符串输出
- fmt.Printf(“%p\n”, &p) 输出一个指针的值
8.map
var m map[string] string
m是声明的变量名,string是对应的Key的类型,string是value的类型,因此这个是声明了一个key和value都是string的map.
创建:
m := make(map[string]int)
m := make(map[string]int)
m["keke"] = 001
m["jame"] = 002
9.json
- json解析到结构体
func Unmarshal(data []byte, v interface{}) error
- // 序列化 结构体=> json
func Marshal(v interface{}) ([]byte, error)