106【GoLand-基础2】(二)

简介: 106【GoLand-基础2】
(3).数组类型

数组是相同数据类型的一组数据的集合,数组一旦定义长度就不能修改,数组可以通过下标(或者索引)来访问元素。

1.数组的定义
var identify [n]type=[n]type{value}
2.假如说定义的数组长度没有超过定义的长度,那么就补空
3.数组的初始化,用"..."可以不用设置固定长度,会自动根据我们添加的值进行分配空间
var identify=[...]int{xxx}
4.可以指定索引赋值  arr := [...]int{索引:value,索引:value}
arr := [...]int{0: 1, 2: 2, 5: 3}
  for _, i2 := range arr {
    println(i2)
  }
-> 1 0 2 0 0 3  
5.数组的值可以被修改,不像字符串那样不可以被修改。
6.获取数组的长度 len(identify)
7.数组的遍历: 普通for 增强for
-----------
(4).切片类型 -> 引用类型
  1. 切片的定义和初始化

切片同属的讲:就是一个动态数组,增加了自动扩容的功能。切片是一个拥有相同类型元素的可变长度的序列。

1.切片的定义: 声明一个数组只要不添加长度即可
(1). var identify []type=[]type{}
(2). identify []type
(3). identify:=[]type{}
2.切片是引用类型,可以使用make函数来创建切片。
var slice []type=make([]type,len)
可以简写为:
slice:=make([]type,len)
make([]T,len,capacity) ->这里的len是数组的长度并且是切片的初始长度
3.获取长度  len(str) csp(str)
-------------------------------------
4.切片的初始化->和数组的初始化一样
identify:=[]type{xxxx}
5.切片的初始化使用数组->可以先设置一个数组然后切片切取
s:=[3]int{1,2,3} -> slice:=s[:]
6.切片的遍历 和数组的遍历一样 for 和 增强for

切片是一个动态数组,可以使用append()函数添加元素,go语言中并没有删除元素的专用方法,我们可以使用切片本身的特性来删除元素,由于,切片是引用类型,通过赋值的方式,会修改原有的内容,go提供copy()函数来拷贝切片

  1. 切片的CRUD

make() 用于分配地址

1.添加元素 
append(数组,添加的元素)
(1).添加到元素的尾部
  var str = []int{}
  ints := append(str, 10, 20, 30) //进行添加的操作
(2).添加到指定元素的后面
---- 整形指定位置插入
func insertByIndex(index int, value int, slice []int) []int {
  var str2 = make([]int, len(slice))
  copy(str2, slice)                   //把ints拷贝给str2
  str3 := []int{}                     //定义一个空切片
  str3 = append(slice[:index], value) //先获取头部
  str3 = append(str3, str2[index:]...)
  return str3
}
----------
2.删除元素
(1).利用空切片进行删除的操作  ints->是一个数组,删除索引为1的值
  var slice []int = []int{}
  intss := append(slice, ints[:1]...)
  intss = append(intss, ints[2:]...)
  fmt.Printf("%d", intss)
(2).直接追加的方式删除  A=append(a[:index],a[index+1]...)
  ints = append(ints[:1], ints[2:]...)
  fmt.Printf("%d", intss)
3.修改 -> 
直接 slice[index]=?
4.查找
(1).通过下标进行寻找  -> slice[index]
(2).通过值进行查找索引  ->遍历
----------------------------
5.  copy()函数
(1).如果是直接赋值的话,那么内存地址一样,修改s2的时候同一个地址的s1也会被修改
直接赋值: ---->s1:=s2
(2).如果利用copy()函数的话,那么内存地址不一样。修改s2那么s1不会改动
基本步骤: 
 先分配给s1地址->  var s2=make([]int,4) //切片类型,四个空间
 开始拷贝 copy(s1,s2) -> 意思就是把s2拷贝给s1
(5).函数类型 ✅

函数在go语言中属于 一级公民 ,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型,这些构成了函数的签名

1 Go语言中函数的特性

  1. go语言中有3中函数: 普通函数匿名函数方法(定义在struct上的函数)
  2. Go语言中不允许函数重载,也就是说不允许函数同名
  3. Go语言中的函数不能嵌套函数但可以嵌套匿名函数
  4. 函数可以作为参数传递给另一个函数
  5. 函数的返回值可以是一个函数
  6. 函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数
  7. 函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再讲副本传递给函数
  8. 函数参数可以没有名称
  1. Go语言函数的定义
1. 定义一个普通函数
 func function_name([parameter list] type) [return_type]{
  函数体
}
  1. 函数的返回值

函数可以有0个或则多个返回值,返回值需要指定数据类型,返回值通过return关键字来指定。

  1. return 关键字中指定了参数时,返回值可以不用名称。如果 return 省略参数,则返回值部分必须带名称
  2. 当返回值有名称时,必须使用括号包围,逗号分隔,即使只有一个返回值
  3. 即使返回值重名了,return中也可以强制指定其他返回值的名称,也就是说return的优先级更高。
  4. 命名的返回值时预先声明好的,在函数内部可以直接使用,无需再次声明。命名返回值的名称不能和函数参数名称相同,否则报错提示变量不能重复定义
  5. return 中可以有表达式,但不能出现赋值表达式,这和其他语言可能有所不同。列如 return a+b是正确的,但return c=a+b是错误的。
1. 没有返回值
func test1(){}
2. 有参数且返回值有名字
func test(a int) (sum int){ sum=1+a return sum}
3.有参数但返回值没有名字
func test(a int) (int){sum:=1+a return sum}
4有参数且有多个返回值
func test()(sum int,sum2 int){return sum,sum2}
5.覆盖命名返回值
func test()(a int){return sum} ->sum会覆盖a
6.如果返回值不想要,可以用匿名变量进行接受
  1. Go函数的参数
  1. go函数可以有0个或多个参数,且参数需要指定数据类型
  2. 声明函数时的参数列表叫做形参,调用时传递的参数叫做实参
  3. go语言的函数是通过值传递进行传递的,意味着传递给函数的参数是一个拷贝的副本,形参改变实参不会变化。
  4. go语言的函数可以使用可变长参数,有时候并不能呢确定参数的个数。
1. 可变参数 ->可变参数只能放在最后且只有一个
  func test(args...int){  
  函数体
}
  1. 函数类型和函数变量

可以使用type 关键字来定义一个函数类型

1.定义一个函数类型的f1,f1是一个类型并不是一个变量名
type f1 func(int,int) int
2.相同类型的函数赋值给函数变量
package main
import "fmt"
func test(a int) int {
  return a
}
func main() {
  type f1 func(int) int // 这里的就是定义一个f1这样的类型
  var ff f1  //定义f1类型的变量ff
  ff = test  // 把test变量赋值给ff变量
  fmt.Printf("%v", ff(2)) //开始调用
}
---------------------**********-------------------------

6.高阶函数

go语言的函数,可以作为函数的参数,传递给另外一个函数,可以作为另外一个函数的返回值返回,高阶函数就是参数类型带函数参数的函数

1.go语言函数作为参数
package main
func test(a int) int {
  return a
}
func test2(b int, f func(int) int) int {
  return b + f(b)
}
func main() {
  println(test2(1, test))
}
-------------------

7.匿名函数

go语言函数不能嵌套,但是在函数内部可以定义匿名函数,实现以一下简单功能的调用。所谓匿名的函数就是: 没有名称的函数

语法格式如下:

1.匿名函数的调用和执行
func(){函数体}()
-------
  // 直接执行
  func() {
    println("您好,我是小明")
  }()
2.匿名函数设置变量名 max,只有匿名函数才能设置变量名。  
  // 给匿名设置一个变量名
  max := func(a int, b int) {
    if a > b {
      fmt.Printf("%v", a)
    } else {
      fmt.Printf("%v", b)
    }
  }
  max(1, 2)
  1. 闭包

闭包可以理解成: 定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部链接起来的桥梁。或者说是函数和其引用环境的组合体

闭包指的是一个函数和与其相关的引用环境组合而成的实体,简单说,闭包+函数+引用环境

闭包: 函数内部定义一个函数,且外层函数的返回值类型是内层函数的函数类型。特性: 内层函数可以调用外层变量。外层变量一直在内层函数的作用域里面

外层变量的作用域扩展至内层函数中。前提是函数没有再次被从新分配空间

package main
import "fmt"
func test(a, b int) func(c, d int) int {
  sum1 := a + b //这里是闭包,它只要函数没有再次被定义,那么他的作用域就被内层函数所包含
  sum := func(c, d int) int {
    return sum1 + c + d
  }
  return sum //返回值是内层函数类型
}
func main() {
  f := test(1, 2) //赋值变量类型
  fmt.Printf("%T\n", f)
  fmt.Printf("%v", f(1, 2))
}

  1. 递归

函数内部调用函数自身的函数称为递归函数。

递归函数的最重要的三点:

  1. 递归是自己调用自己
  2. 必须先定义一个函数的退出条件,没有推出条件,递归将称为死循环
  3. go语言递归函数很可能会产生一大堆的栈溢出问题,也很可能会出现占空间内存溢出问题。
package main
func test(a int) int {
  if a == 1 {   //直接返回这个值,不会再向下执行了。
    return 1
  }
  return a + test(a-1)
}
func main() {
  println(test(5))
}
  1. defer 语句

Go语言中的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,即延迟处理的语句按defer定义的逆序进行执行,也就是说: 先被defer的居于最后执行,最后defer的语句最先执行。

defer特性:

  1. 关键字defer用于注册延迟调用
  2. 这些调用直到return前才被执行,因此,可以用来做资源清理
  3. 多个defer语句,按先进后出的方式执行。
  4. defer语句中变量,在defer声明就决定了。
1.如何定义一个defer语句
defer 语句[可以是输出语句/特殊函数]
2.如果有多个defer会按照先定义后执行的顺序进行处理
3.defer,只是进行了延迟的处理,但里面的参数在声明的时候就已经配置好了
  1. init函数

Go语言有一个特殊的函数 init 函数,先于main 函数执行,实现包级别的一些初始化操作

init函数的特点

  1. init先于main函数 自动执行,不能被其他函数所调用
  2. init函数没有输入参数、返回值
  3. 每个包可以有多个init函数
  4. 包的每个源文件也可以有多个init函数,这点比较特殊
  5. 同一个包的init执行顺序,Go没有明确定义,编程时要注意程序不要依赖这个执行顺序
  6. 不同包的init函数按照包导入的依赖关系决定执行顺序

GO初始化顺序

初始化顺序: 变量初始化->init()->main()

1. init函数的定义
func init() { //没有参数、没有返回值 不能被调用
  函数体
}
2.go语言的执行顺序 | 变量初始化->init()->main()
package main
func init() { //没有参数、没有返回值
  println("init........") //  ->2
}
var value int = test() //变量的初始化  ->1
func test() int {
  println("初始化数据....")
  return 100
}
func main() {
  println("main....") //  ->3
}
3.在一个包中可以定义多个init()函数,执行顺序是从上到下
(6).布尔类型
var identify bool=flag
identify:=flag
(7).数字类型

Go语言支持整数和浮点型数字,并且原生支持复数,其中位的运算采用补码。

1.整数类型

有符号(xxx)、无符号(uxxx)。

%d ->十进制取值
  %b->二进制取值 
  %o->八进制取值 
  %x/%X->十六进制

2.浮点型

%f ->取值
%.nf%->保留n位小数 
(8).map类型 -> 引用类型

map是一种 key:value 键值对的数据结构容器。map内部实现是哈希表(hash)。map最重要的一定是通过key来快速检索数据,key类似于索引,指向数据的值。map是引用类型的。

map的定义与初始化

可以使用内建函数make, 也可以使用map关键字来定义map

1. 使用map来定义
var 变量名称 map[key的数据类型]value的数据类型
2. 使用make函数
变量名称:=make(map[key的数据类型]value的数据类型)
(1).两种初始化方式以及两种定义方式
  var m1 map[string]string           //  利用map定义一个map  初始化为空
  m2 := make(map[string]string)      //利用make定义一个map 初始化为空
  var m3 = map[string]string{"name": "李明", "age": "18", "high": "1.75"} //定义并初始化数据
  var m4 = map[string]string{"age": "18"}  //定义并初始化
*******************************
3.通过key值进行查找数据  
  变量名[key]
fmt.Printf("%v", m1["name"])
4.判断某一个key是否存在💥
  v,ok:=变量名[key]  v是value ok是布尔类型
v, ok := m1["name"]

map的遍历

1. 可以只获取key
2. 可以获取key和value
3. 可以只获取value
for key,value:=range 变量名{}
-----
  m1 = map[string]string{"name": "李明", "age": "18", "high": "1.75"} //初始化数据
  for k := range m1 {
    fmt.Printf("%v\t", k)
  }
  for k, v := range m1 {
    fmt.Printf("%v %v ", k, v)
  }
  for _, v := range m1 {
    fmt.Printf("%v\t", v)
  }
(9).结构体类型
  1. 类型定义和类型别名
1.  类型定义语法
type NewType Type  -》等同于Type
------------测试使用
package main
func main() {
  // 类型定义->实际上就是说 MyInt 等同于 int 
  type MyInt int
  // i 为MyInt类型的变量,实际上等同于int类型的变量
  var i MyInt 
  i=100
  println(i)
}
-------------
2. 类型别名定义
type NewType=Type   ->就是起一个别名
-------测试
package main
func main() {
  // 类型别名定义->实际上就是说 MyInt 等同于 int
  type MyInt=int
  // i 为MyInt类型的变量,实际上等同于int类型的变量
  var i MyInt
  i = 100
  println(i)
}
相关文章
|
6月前
|
Go
GoLand创建项目过程
GoLand创建项目过程
95 0
|
Cloud Native 测试技术 Go
你不知道的goland技巧
你不知道的goland技巧
100 0
|
关系型数据库 Go
106【GoLand-基础2】(四)
106【GoLand-基础2】
83 0
|
IDE Go 开发工具
Go开发IDE全览:GoLand vs VSCode全面解析
Go开发IDE全览:GoLand vs VSCode全面解析
509 0
|
IDE Go 开发工具
【Go·编辑器IDE】GoLand集成开发环境安装及使用教程
【Go·编辑器IDE】GoLand集成开发环境安装及使用教程
【Go·编辑器IDE】GoLand集成开发环境安装及使用教程
|
3月前
|
Rust Shell 开发者
7步开始rust(自定义环境安装与vscode开发环境配置)
本文档详细记录了当改变Rust安装路径至特定目录(如 `/home/local_rust`)时,如何在VSCode环境中正确配置Rust开发环境的过程。主要包括:设置环境变量、使用清华大学镜像安装Rust及更新镜像源、手动部署 `rust-analyzer`、安装标准库源码、安装与配置VSCode插件等七个步骤,确保开发者能够顺利搭建并使用定制化的Rust开发环境。
517 0
|
5月前
|
IDE Linux Go
|
6月前
|
Java Python
pycharm-ieda-phpstorm超级好用插件,一键解释代码
pycharm-ieda-phpstorm超级好用插件,一键解释代码
|
6月前
|
Python
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
218 0
|
6月前
|
Go 开发工具
编程笔记 GOLANG基础 004 GOLANG常用命令及VSCODE快捷键
编程笔记 GOLANG基础 004 GOLANG常用命令及VSCODE快捷键
111 2