- 变量声明
var 变量名 数据类型,可以同时赋值,另一种方式只能在函数内部,变量名:=数据值,以及多变量声明
全局变量声明必须以 var 关键字开头,如果想要在外部包中使用全局变量的首字母必须大写,go语言区分大小写。go不支持重载,隐式转换,动态链接库,动态加载加载代码
统自动赋予它该类型的零值:int 为 0,float 为 0.0,bool 为 false,string 为空字符串,指针为 nil, byte 只能操作简单的字符,不支持中文操作 rune指任意字符var a int=1 标准 函数外部全局变量 var a,b=1,"ok" 标准 b :=2.1 简化只能用于函数内部 i,j:=1,2 简化 _,a :=1,2 _ 表示匿名变量,会丢弃 const pi=3.14 常量定义
- 整形int浮点型float
int8 -128-127 int16 int32 int64 rune是int32别称
uint8 0-255 uint16 uint32 uint64 无符号整型 byte是uint8别称
uint 32位上就是uint32,64位上uint64
int 32位上就是int32,64位上就是int64
uintptr 无符号整型,用于存放一个指针
float32 float64 浮点型 默认是64位
var x complex128 = complex(1, 2) 表示64位复数 1+2i ,默认64位,包含实数和虚数
别名
rune int32
byte uint8
any interface{}bool 布尔型只有true,false默认值是false,不允许强制转换成布尔型
字符串String
\n:换行符
\r:回车符
\t:tab 键
\u 或 \U:Unicode 字符
\:反斜杠自身
- 字符串连接,多行放到行头
str :=”123”
+”456”
多行字符串反双引号 `` 普通双引号没有单引号 ""
fmt.Sprintf("采集第%s页成功",var)
b3 := []byte("test")字符串申明
s1 := "abc" 常规申明
将[]byte转为string,语法string([]byte)
将string转为[]byte,语法[]byte(string)
错误类型error
err :=”错误”
- 单字母 byte
var ch byte = 65 表示A var a := '中' s1 := "big" byteS1 := []byte(s1) byteS1[0] = 'p' fmt.Println(string(byteS1)) pig s2 := "白萝卜" runeS2 := []rune(s2) runeS2[0] = '红' fmt.Println(string(runeS2)) 红萝卜
- 类型转换,必须显示转换
b:=int(b)
str:=strconv.Itoa(int) 整型转换成字符串
string:=strconv.FormatInt(int64,10)
string := strconv.FormatFloat(float32, 'E', -1, 32)
string := strconv.FormatFloat(float64, 'E', -1, 64)
str:=fmt.Sprintf("%d", int64(34839212984328))
int,_:=strconv.Atoi(str) 字符串转换整型
int64,_:= strconv.ParseInt(str, 10, 64)
float,_ := strconv.ParseFloat(str,32/64)
- 变量,常量,包都可以分组声明
import () const() var() - 枚举类型enum,默认0
const(
x=iota //0
y=iota //1
z //2
)
x=iota //0 - 指针类型,在变量前添加&,指针取值符号 *,空指针nil
- 常量 const pi=3.14233 值可以确定
- 数组array
没有空数组概念
var q [3]int = [3]int{1, 2, 3}
q := [...]int{1, 2, 3} 自动确定长度,长度0开始
arr:= [3]string{"nihk", "你好吗", "测试11"}
a:=[6]interface{}{1,2,3,4,true,"wo"}
arr := new([3]int)
arr[0] = 1
arr[1] = 3
arr[2] = 4
for i:=0;i<len(arr);i++{
fmt.Println(arr[i])
}
for k, v := range arr {
fmt.Println(k, v)
}
easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}} 多维数组
m := [...]int{
'a': 1,
}
fmt.Println(len(m))//98
- 切片slice
默认空切片nil,长度0,引用类型
var strList []string 字符串切片
var str [][]string 多维切片,元素类型是[]string
var numListEmpty = []int{} 空切片
slice := []byte {'a', 'b', 'c', 'd'} 声明切片简化
a=slice[1:3:7] 第三个参数容量
a = append(a, 1, 2, 3) 切片追加元素
a=append([]string{"2.7.1","3.2.1","3.3.1","3.4.1"},a...)//头部追加
a=append(a,a1...) 合并切片
a := make([]int, 2, 10) 构造切片,切片2是元素已用2个,一共十个
cap获取容量
len(a) == 0 判断切片是否为空
从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]...)
a := []string{"中国", "美国", "日本"}
a = append(a, "韩国") //尾部追加,支持多个元素
a = append(a, []string{"英国"}...) //追加切片
a = append([]string{"法国"}, a...) //头部追加切片
index := 2 //要删除位置
a = append(a[:index], a[index+1:]...)
a = append(a, "") // 切片扩展1个空间
i := 2 //要插入位置
copy(a[i+1:], a[i:]) // a[i:]向后移动1个位置
a[i] = "冰岛" // 设置新添加的元素
x := []string{"泰国", "新加坡"}//添加切片到任意位置
a = append(a, x...) // 为x切片扩展足够的空间
copy(a[i+len(x):], a[i:]) // a[i:]向后移动len(x)个位置
copy(a[i:], x)
计算字符个数 m:=len([]rune(str))
arr:=[]int{1,2,3,4,5}
arr=arr[:len(arr)-1] 删除最后一个元素后新切片[1,2,3,4]
arr=arr[len(arr)-1] 取出最后一个元素5
arr=arr[:1]取出第一个组成的新切片 [1]
arr:=append(arr[:2],arr[2+1:]...) [1,2,4,5] 删除的是第2个3
arr=arr[1:3] 取出的是[2,3]只有两个
arr[:]等价于 arr[0:len(arr)] 也就是拷贝整个切片
arr[1:]等价于arr[1:len(arr)] 取出[2,3,4,5]
arr[len(arr)-10:] 最后10个
arr[:2]等价于arr[0:2]
切片的切片,任意类型多维切片处理
c:=[]interface{}{[]interface{}{1,"io","op"},[]interface{}{2,"你好","是吗"}}
for _,d:=range c{
fmt.Println(d)
x:=d.([]interface{})
fmt.Println(x[0],x[1],x[2])
}
- map 又叫做字典,映射,关键数组,hash(哈希表),支持len,是引用类型,默认nil
a:= make(map[string]int) //声明并初始化
var a map[int]string
var a map[string]map[string]string
var a map[string]interface{}//支持任意类型值,输出时候需要使用断言
a = make(map[string]string) //用make初始化才能用,简化的不用
a["a"]=1 //赋值,赋值前必须make
a := map[string]float32{"C":5, "Go":4.5, "Python":4.5, "C++":2 }简化
a:= map[string]interface{}{"qq":true,"ss":1} 简化
a=make(map[string]string)//清空a
delete(maps, "C") 删除元素
v,k :=a["喜欢"] 判断key是否存在
if k{
fmt.Println(v)
}
for i, v := range a { //无顺序遍历
fmt.Println(i, v)
}
var mapSlice = make([]map[string]string, 3) k为切片
var sliceMap = make(map[string][]string, 3)值为切片切片字典{"aa":[]string{"w"}}
解析json字符串为map
jsons:=`{"a":"中国","b":"日本"}`
var tempMap map[string]interface{}
json.Unmarshal([]byte(jsons), &tempMap)
fmt.Println(tempMap["a"])
解析json字符串为scile
jsons:=`[{"a":"中国","b":"日本"}]`
var tempMap []map[string]interface{}
json.Unmarshal([]byte(jsons), &tempMap)
fmt.Println(tempMap)
map 转换成json
m:= map[string]string{"a":"中国","b":"日本"}
data,_:=json.MarshalIndent(m,""," ")
fmt.Println(string(data))
结构体转json
type BK struct {
Name string `json:"name"`
Code string `json:"code"`
}
bks:=[]BK{
BK{Name:"li",Code:"123",},
}
datas,_:=json.Marshal(bks)
fmt.Println(string(datas))
json转换结构体
var bks []BK
json.Unmarshal([]byte(str), &bks)
循环Map interface{}
data1:=tempMap.(map[string]interface{}) //这里data1是 [][]interface{}
for _,v:=range data1.([]interface{}){
fmt.Print(v)
}
Map转换成结构体 sc是结构体
var tempMap sc
arr1,_ := json.Marshal(ss)
json.Unmarshal(arr1,&tempMap)
json转换map
js:=`{"data":{"a":123}}`
var j map[string]map[string]int
json.Unmarshal([]byte(js),&j)
fmt.Println(j["data"]["a"])
any 转换 []string
strings,_ := rs["gover"].([]interface{})
array := make([]string, len(strings))
for i, v := range strings {
array[i] = v.(string)
}
- channel 管道类型,是引用类型,必须make初始化后使用
var c chan int //存放整数,长度用len 容量cap
var c chan map[int]string //存放map
c=make(chan int,3) //存放3个值
c1<- 10//发送10
c2:=<-c1//接收值
读取写入用for循环,次数要一致
for i := 0; i < 10; i++ {
c <- 8 * i
}
close(c)//写完必须关闭否则出错
for {
for data := range c {
fmt.Print(data,"\t")
}
break
}//读取结束
流程控制
- if else,左括号和关键词同一行,Go的if还有一个强大的地方就是条件判断语句里面允许声明一个变量,这个变量的作用域只能在该条件逻辑块内,其他地方就不起作用了
if condition1 { } else if condition2 { }else { }
- 循环for只有一个
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
实现while
sum := 1
for sum < 1000 {
sum += sum
}
for k,v:=range map {
fmt.Println("map's key:",k)
fmt.Println("map's val:",v)
}
丢弃不要变量
for _, v := range map{
fmt.Println("map's val:", v)
}
for y := 1; y <= 9; y++ {
// 遍历, 决定这一行有多少列
for x := 1; x <= y; x++ {
fmt.Printf("%d*%d=%d ", x, y, x*y)
}
fmt.Println()
}
- switch
var a = "hello" switch a { case "hello": fmt.Println(1) case "mum", "daddy"://多分支 fmt.Println(2) default: fmt.Println(0) }
- goto 跳出多重循环;
break 语句可以结束 for、switch 和 select 的代码块;
continue 语句可以结束当前循环,开始下一次的循环迭代过程,仅限在 for 循环内使用;函数,大写字母开头可导出
- 函数定义,支持多返回值,返回值初始化0,
func hypot(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
func typedTwoValues() (int, int) {
return 1, 2
}
func SumAndProduct(A, B int) (add int, Multiplied int) {//命名返回值
add = A+B
Multiplied = A*B
return
}
匿名函数,传递后可以调用
f := func(data int) {
fmt.Println("hello", data)
}
可变参数
func myfunc(args ...int) {
for _, arg := range args {
fmt.Println(arg)
}
}
递归阶乘
func Factorial(n uint64) (result uint64) {
if n > 0 {
result = n * Factorial(n-1)
return result
}
return 1
}
指针
func add1(a *int) int { // 请注意,
*a = *a+1 // 修改了a的值
return *a // 返回新值
}
x1 := add1(&x)
func add(a int,b int)(c int,err error){//错误处理
if(a<0){
err = errors.New("不能小于0")
return
}
c= a+b
return
}
- defer
Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。特别是当你在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前你需要关闭相应的资源,不然很容易造成资源泄露等问题,后进先出
返回 5,4,3,2,1,0for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) }
struct 结构体复杂类型
type Point struct {
X int
Y int
}
var p Point 初始化结构体
p.X = 10
p.Y = 20
test :=new(Point) 指针类型结构体初始化
test := &Point{
name:"测试"
} 去结构体地址实例化
//json结构体
type Xx struct {
ID int `json:"id"`
Name string `json:"name"`
}
ok:=Xx{
ID:2,
Name:"中国",
}
j,_:=json.Marshal(ok)
type User struct {
Email string `json:"email"`
Password string `json:"password"`
Isok bool `json:"isok,omitempty"`//忽略值是空的字段
Tid int `json:"tid,string"` //支持字符串数字
Id int `json:"_"`//忽略字段
UserName string `json:"user_name"`
}
s:=User{
Email:"logove@qq.com",
Password: "13333",
Isok:true,
Tid:11,
Id:12,
UserName: "李白",
}
ss,_:=json.Marshal(s)
fmt.Println(string(ss))
面向对象method,下面是求圆和长方形
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
func (r Rectangle) area() float64 {
return r.width*r.height
}
func (c Circle) area() float64 {
return c.radius * c.radius * math.Pi
}
//定义一个类
type Student struct {
id uint
name string
male bool
score float64
}
//继承父类,支持重写函数,支持继承多个类
type S1 struct {
Student
}
//定初始化一个类,New+类名
func NewStudent(id uint, name string, score float64) *Student {
return &Student{id: id, name:name, score:score}
}
//定义方法
func (s Student) GetName() string {
return s.name
}
//设置变量,传入指针
func (s *Student) SetName(name string) {
s.name = name
}
//格式化打印扩展String方法
func (s Student) String() string {
return fmt.Sprintf("{id: %d, name: %s, male: %t, score: %f}",
s.id, s.name, s.male, s.score)
}
声明接口,Go没有类与继承概念
type writer interface{
Write([]byte) error
}
包的绝对路径就是“$GOROOT/src 或 $GOPATH/src”后面包的源码的全路径
import "lab/test"
源码位于$GOPATH/src/lab/testimport "fmt"
标准引用import F "fmt"
别名引用
- 定义包 package 包名
- 类型、变量、常量首字母大写表示外部可以引用,导出
- 导入 import (“a1”,”a2”)
- GOPATH 项目目录建议跟随项目走,不设置全局,初始化函数func init(){}
v := reflect.TypeOf(x)判断变量类型 - 25个关键字
var和const参考2.2Go语言基础里面的变量和常量申明
package和import已经有过短暂的接触
func 用于定义函数和方法
return 用于从函数返回
defer 用于类似析构函数
go 用于并发
select 用于选择不同类型的通讯
interface 用于定义接口,参考2.6小节
struct 用于定义抽象数据类型,参考2.5小节
break、case、continue、for、fallthrough、else、if、switch、goto、default这些参考2.3流程介绍里面
chan用于channel通讯
type用于声明自定义类型
map用于声明map类型数据
range用于读取slice、map、channel数据
make用于内建类型(map、slice、channel)的内存分配,也用于返回数组
z := make([]Struct, 0)等同var z Struct等同z:=Struct{}等同z:=&Struct{}
new 用于结构体初始化 z := new(Struct)运算符
!非 &&和 ||或 ==等于 !=不等于 %t格式化布尔值
%d 格式化数字 %x %X格式化十六进制
%g 浮点数 %f浮点数 %e科学计数法
文档更新时间: 2022-08-17 12:35 作者:Yoby