当前位置: 首页 > news >正文

Gin入门笔记

1.基本数据类型

整型

类型占用存储空间
int32位系统4字节
64位系统8字节
unint32位系统4字节
64位系统8字节
int81字节
int162字节
int324字节
int648字节
uint81字节
uint162字节
uint324字节
uint648字节
rune4字节(等价int32)
byte1字节(等价unint8)

Unicode字符rune类型是和int32等价的类型,通常用于表示一个Unicode码点。这两个名称可以互换使用。

同样byte也是uint8类型的等价类型,byte类型一般用于强调数值是一个原始的数据而不是一个小的整数。Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。

浮点型

类型占用存储空间
float324字节
float648字节

布尔型

布尔类型也叫bool类型,bool类型数据只允许取值true和false,占用一个字节

字符串

字符串也叫string类型,是一串固定长度的字符连接起来的字符序列。

字符串的表示形式:
(1)如果字符串中没有特殊字符,字符串的表示形式用双引号
(2)如果字符串中有特殊字符,字符串的表示形式用反引号 ``

常量

常量使用const声明,常量的值不可修改

所有常量的运算都可以在编译期完成,这样可以减少运行时的工作,也方便其他编译优化。当操作数是常量时,一些运行时的错误也可以在编译时被发现,例如整数除零、字符串索引越界、任何导致无效浮点数的操作等。

常量间的所有算术运算、逻辑运算和比较运算的结果也是常量,对常量的类型转换操作或以下函数调用都是返回常量结果:len、cap、real、imag、complex和unsafe.Sizeof(§13.1)。

复数

complex64 32位浮点型数

complex128 64位浮点型数

Go语言提供了两种精度的复数类型:complex64和complex128,分别对应float32和float64两种浮点数精度。内置的complex函数用于构建复数,内建的real和imag函数分别返回复数的实部和虚部:

var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y)                 // "(-5+10i)"
fmt.Println(real(x*y))           // "-5"
fmt.Println(imag(x*y))           // "10"

在常量算术规则下,一个复数常量可以加到另一个普通数值常量(整数或浮点数、实部或虚部),我们可以用自然的方式书写复数,就像1+2i或与之等价的写法2i+1。上面x和y的声明语句还可以简化:

x := 1 + 2i
y := 3 + 4i

默认值

在Golang中数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值(默认值又叫零值)

数据类型默认值
整数类型0
浮点类型0
布尔类false
字符串类型“”

类型转换

显示转换

Go在不同类型的变量之间赋值时需要显式转换,并且只有显式转换(强制转换)。

语法:
表达式T(v)将值v转换为类型T
T : 就是数据类型
v : 就是需要转换的变量

基本数据类型转换为string

方式1:fmt.Sprintf(“%参数”,表达式) —》 重点练习这个,推荐方式

package main
import "fmt"
func main(){var n1 int = 19var n2 float32 = 4.78var n3 bool = falsevar n4 byte = 'a'var s1 string = fmt.Sprintf("%d",n1)fmt.Printf("s1对应的类型是:%T ,s1 = %q \n",s1, s1)var s2 string = fmt.Sprintf("%f",n2)fmt.Printf("s2对应的类型是:%T ,s2 = %q \n",s2, s2)var s3 string = fmt.Sprintf("%t",n3)fmt.Printf("s3对应的类型是:%T ,s3 = %q \n",s3, s3)var s4 string = fmt.Sprintf("%c",n4)fmt.Printf("s4对应的类型是:%T ,s4 = %q \n",s4, s4)
}

方式2:使用strconv包的函数

package main
import("fmt""strconv"
)
func main(){var n1 int = 18var s1 string = strconv.FormatInt(int64(n1),10)   //参数:第一个参数必须转为int64类型 ,第二个参数指定字面值的进制形式为十进制fmt.Printf("s1对应的类型是:%T ,s1 = %q \n",s1, s1)var n2 float64 = 4.29var s2 string = strconv.FormatFloat(n2,'f',9,64)//第二个参数:'f'(-ddd.dddd)  第三个参数:9 保留小数点后面9位  第四个参数:表示这个小数是float64类型fmt.Printf("s2对应的类型是:%T ,s2 = %q \n",s2, s2)var n3 bool = truevar s3 string = strconv.FormatBool(n3)fmt.Printf("s3对应的类型是:%T ,s3 = %q \n",s3, s3)
}
string转换为基本数据类型

使用strconv包的函数

strconv.ParseT

2.复合数据类型

数组

var 数组名 [数组大小]数据类型

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

数组的每个元素可以通过索引下标来访问,索引下标的范围是从0开始到数组长度减1的位置。内置的len()函数将返回数组中元素的个数。

arr中存的是地址值,和arr[0]arr[0][0]地址相同

数组的初始化
//第一种:
var arr1 [3]int = [3]int{3,6,9}
fmt.Println(arr1)
//第二种:
var arr2 = [3]int{1,4,7}
fmt.Println(arr2)
//第三种:
var arr3 = [...]int{4,5,6,7}
fmt.Println(arr3)
//第四种:
var arr4 = [...]int{2:66,0:33,1:99,3:88}
fmt.Println(arr4)

注意:

  1. 长度属于类型的一部分
  2. Go中数组属值类型,在默认情况下是值传递,因此会进行值拷贝
  3. 如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)
二维数组的遍历
package main
import "fmt"
func main(){//定义二维数组:var arr [3][3]int = [3][3]int{{1,4,7},{2,5,8},{3,6,9}}fmt.Println(arr)fmt.Println("------------------------")//方式1:普通for循环:for i := 0;i < len(arr);i++{for j := 0;j < len(arr[i]);j++ {fmt.Print(arr[i][j],"\t")}fmt.Println()}fmt.Println("------------------------")//方式2:for range循环:for key,value := range arr {for k,v := range value {fmt.Printf("arr[%v][%v]=%v\t",key,k,v)}fmt.Println()}
}

Slice

slice斯莱丝

一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。内置的len和cap函数分别返回slice的长度和容量。

创建切片:

方式1:定义一个切片,然后让切片去引用一个已经创建好的数组。

sl := arr[2:4]

方式2:通过make内置函数来创建切片。基本语法: var 切片名 = make([]T, len,[cap]

sl2 := make([]int, 2, 3)

方式3:定一个切片,直接就指定具体数组,使用原理类似make的方式。\

sl3 := []int{1, 2, 3}
append函数

切片可以动态增长

package main
import "fmt"
func main(){//定义数组:var intarr [6]int = [6]int{1,4,7,3,6,9}//定义切片:var slice []int = intarr[1:4] //4,7,3fmt.Println(len(slice))slice2 := append(slice,88,50)fmt.Println(slice2) //[4 7 3 88 50]fmt.Println(slice)//底层原理://1.底层追加元素的时候对数组进行扩容,老数组扩容为新数组://2.创建一个新数组,将老数组中的4,7,3复制到新数组中,在新数组中追加88,50//3.slice2 底层数组的指向 指向的是新数组 //4.往往我们在使用追加的时候其实想要做的效果给slice追加:slice = append(slice,88,50)fmt.Println(slice)//5.底层的新数组 不能直接维护,需要通过切片间接维护操作。
}

可以通过append函数将切片追加给切片

slice3 := []int{99,44}
slice = append(slice,slice3...)
fmt.Println(slice)
切片的拷贝
//定义切片:
var a []int = []int{1,4,7,3,6,9}
//再定义一个切片:
var b []int = make([]int,10)
//拷贝:
copy(b,a) //将a中对应数组中元素内容复制到b中对应的数组中
fmt.Println(b)

注意:

切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用

切片使用不能越界,如果切片操作超出cap(s)的上限将导致一个panic异常

Map

var map变量名 map[keytype]valuetype
创建方式
//方式1:
//定义map变量:
var a map[int]string
//只声明map内存是没有分配空间
//必须通过make函数进行初始化,才会分配空间:
a = make(map[int]string,10) //map可以存放10个键值对
//将键值对存入map中:
a[20095452] = "张三"
a[20095387] = "李四"
//输出集合
fmt.Println(a)
//方式2:
b := make(map[int]string)
b[20095452] = "张三"
b[20095387] = "李四"
fmt.Println(b)
//方式3:
c := map[int]string{20095452 : "张三",20098765 : "李四",
}
c[20095387] = "王五"
fmt.Println(c)
map的特点:

(1)map集合在使用前一定要make
(2)map的key-value是无序的
(3)key是不可以重复的,如果遇到重复,后一个value会替换前一个value
(4)value可以重复的

package main
import "fmt"
func main(){//定义map变量:var a map[int]string//只声明map内存是没有分配空间//必须通过make函数进行初始化,才会分配空间:a = make(map[int]string,10) //map可以存放10个键值对//将键值对存入map中:a[20095452] = "张三"a[20095387] = "李四"a[20097291] = "王五"a[20095387] = "朱六"a[20096699] = "张三"//输出集合fmt.Println(a)
}
操作

【1】增加和更新操作:
map[“key”]= value ——》 如果key还没有,就是增加,如果key存在就是修改。
【2】删除操作:
delete(map,“key”) , delete是一个内置函数,如果key存在,就删除该key-value,如果k的y不存在,不操作, 但是也不会报错
【3】清空操作:
(1)如果我们要删除map的所有key ,没有一个专门的方法一次删除,可以遍历一下key,逐个删除
(2)或者map = make(…),make一个新的,让原来的成为垃圾,被gc回收
【4】查找操作:
value ,bool = map[key]
value为返回的value,bool为是否返回 ,要么true 要么false
【5】获取长度:len函数

结构体

结构体定义
//定义老师结构体,将老师中的各个属性  统一放入结构体中管理:
type Teacher struct{//变量名字大写外界可以访问这个属性Name stringAge intSchool string
}
实例创建方式

1.直接创建

//创建老师结构体的实例、对象、变量:
var t1 Teacher // var a int
fmt.Println(t1) //在未赋值时默认值:{ 0 }
t1.Name = "马士兵"
t1.Age = 45
t1.School = "清华大学"
fmt.Println(t1)
fmt.Println(t1.Age + 10)

2.创建时赋值

var t Teacher = Teacher{"赵珊珊",31,"黑龙江大学"}
fmt.Println(t)

3.返回的是结构体指针

var t *Teacher = new(Teacher)
(*t).Name = "马士兵"
(*t).Age = 45
//为了符合程序员的编程习惯,go提供了简化的赋值方式
t.School = "清华大学"
//go编译器底层对t.School转化(*t).School = "清华大学"
fmt.Println(*t)

4.返回的是结构体指针,创建时赋值

var t *Teacher = &Teacher{"马士兵",45,"清华大学"}
fmt.Println(t)
结构体之间的转换

结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字、个数和类型)

package main
import "fmt"
type Student struct {Age int
}
type Person struct {Age int
}
func main(){var s Student = Student{10}var p Person = Person{10}s = Student(p)fmt.Println(s)fmt.Println(p)
}

结构体进行type重新定义(相当于取别名),Golang认为是新的数据类型,但是相互间可以强转

package main
import "fmt"
type Student struct {Age int
}
type Stu Student
func main(){var s1 Student = Student{19}var s2 Stu = Stu{19}s1 = Student(s2)fmt.Println(s1)fmt.Println(s2)
}
嵌入匿名结构体

在结构体中嵌入匿名结构体能继承嵌入结构体的字段和方法,从而实现oop的继承特性,提高代码复用性

组合

如果一个struct嵌套了一个有名结构体,这种模式就是组合,如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字。

3.流程控制

分支结构

if

表达式外无需小括号 ( ),而大括号 { } 则是必须的。

switch
switch 表达式 {case1,2,..:语句块1case3,4,...:语句块2....default:语句块
}

无条件 switch:

无条件的 switch 同 switch true 一样。

注意:

  1. switch后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
  2. case后面的值如果是常量值(字面量),则要求不能重复
  3. case后的各个值的数据类型,必须和 switch 的表达式数据类型一致
  4. case后面可以带多个值,使用逗号间隔。比如 case 值1,值2…
  5. case后面不需要带break
  6. default语句不是必须的,位置也是随意的。
  7. switch穿透,利用fallthrough关键字,如果在case语句块后增加fallthrough ,则会继续执行下一个case

循环结构

for

Go 的 for 语句后面的三个构成部分外没有小括号, 大括号 { } 则是必须的。

for 是 Go 中的「while」 分号可以去掉,和C中的while类似

如果省略循环条件,该循环就不会结束,因此无限循环可以写得很紧凑。

for range
for key, val := range coll {...
}

关键字

break

结束最近的循环

continue

结束本次循环,继续下一次循环

goto

Golang的 goto 语句可以无条件地转移到程序中指定的行。
goto语句通常与条件语句配合使用。可用来实现条件转移.
在Go程序设计中一般不建议使用goto语句,以免造成程序流程的混乱。-

return

结束当前的函数

4.函数

定义:

func function_name( [parameter list] ) [return_types] {函数体
}
闭包

Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。

匿名函数是一种没有函数名的函数,通常用于在函数内部定义函数,或者作为函数参数进行传递。

以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包中递增 i 变量,代码如下:

package mainimport "fmt"func getSequence() func() int {i:=0return func() int {i+=1return i  }
}func main(){/* nextNumber 为一个函数,函数 i 为 0 */nextNumber := getSequence()  /* 调用 nextNumber 函数,i 变量自增 1 并返回 */fmt.Println(nextNumber())fmt.Println(nextNumber())fmt.Println(nextNumber())/* 创建新的函数 nextNumber1,并查看结果 */nextNumber1 := getSequence()  fmt.Println(nextNumber1())fmt.Println(nextNumber1())
}//执行结果//1//2//3//1//2

5.接口

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

接口可以让我们将不同的类型绑定到一组公共的方法上,从而实现多态和灵活的设计。

Go 语言中的接口是隐式实现的,也就是说,如果一个类型实现了一个接口定义的所有方法,那么它就自动地实现了该接口。因此,我们可以通过将接口作为参数来实现对不同类型的调用,从而实现多态。

/* 定义接口 */
type interface_name interface {method_name1 [return_type]method_name2 [return_type]method_name3 [return_type]...method_namen [return_type]
}/* 定义结构体 */
type struct_name struct {/* variables */
}/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {/* 方法实现*/
}

6.错误处理

defer+recover机制处理错误
package mainimport "fmt"func main() {test()fmt.Println("上面的除法操作执行成功")fmt.Println("正常执行下面的逻辑")
}
func test() {//利用defer+recover来捕获错误:defer后加上匿名函数的调用defer func() {//调用recover内置函数,可以捕获错误:err := recover()//如果没有捕获错误,返回值为零值:nilif err != nil {fmt.Println("错误已捕获")fmt.Println("err是:", err)}}()num1 := 10num2 := 0result := num1 / num2fmt.Println(result)
}
自定义错误

需要调用errors包下的New函数:函数返回error类型

func test() (err error){...return errors.New("除数不能为零")
}
err := test()
if err != nil {fmt.Println("自定义错误:",err)
}

有一种情况:程序出现错误以后,后续代码就没有必要执行,想让程序中断,退出程序:
借助:builtin包下内置函数:panic

err := test()
if err != nil {fmt.Println("自定义错误:",err)panic(err)
}
//下面代码不会执行

http://www.mrgr.cn/news/64326.html

相关文章:

  • Soft TeacherEnd-to-End Semi-Supervised Object Detection with Soft Teacher
  • 第二章 IP、子网划分、VR
  • CSS网页布局综合练习(涵盖大多CSS知识点)
  • 使用Vue.js和Vuex构建可维护的前端应用
  • atomic physics — half life of nuclear decay
  • 2-140 基于Solidworks和Matlab Simulink Simscape仿真的机器人手臂仿真
  • 深度学习基础—序列采样
  • 网络:ARP的具体过程和ARP欺骗
  • MATLAB中sort函数用法
  • 【Kaggle | Pandas】练习6:重命名和组合
  • cn.afterturn.easypoi.exception.excel.ExcelExportException: Excel导出错误 -> 修正过程。
  • (九)JavaWeb后端开发——Servlet
  • 【机器学习】回归树
  • 微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析
  • 异步回调之Join
  • 第十七课 component组件解析
  • Rust语言有哪些常用语句?
  • zyb 的 Codeforces Round 983 (Div. 2)
  • WPF+MVVM案例实战(十八)- 自定义字体图标按钮的封装与实现(ABD类)
  • Python使用K-means实现文本聚类
  • Respiratory Physiology Neurobiology
  • TCP编程-socket(套接字)编程实战1
  • RK3568平台开发系列讲解(中断篇)延迟工作实验
  • vscode makfile编译
  • 电阻基础知识(六)-电阻的失效模式和失效机理
  • 【MacOS实操】如何基于SSH连接远程linux服务器