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

go基础语法10问(2)

1.recover的执行时机

无,recover 必须在 defer 函数中运行。recover 捕获的是祖父级调用时的异常,直接调用时无效。

func main() {recover()panic(1)
}

直接 defer 调用也是无效。

func main() {defer recover()panic(1)
}

defer 调用时多层嵌套依然无效。

func main() {defer func() {func() { recover() }()}()panic(1)
}

必须在 defer 函数中直接调用才有效。

func main() {defer func() {recover()}()panic(1)
}

2.闭包错误引用同一个变量问题怎么处理

在每轮迭代中生成一个局在这里插入代码片部变量 i 。如果没有 i := i 这行,将会打印同一个变量。

func main() {for i := 0; i < 5; i++ {i := idefer func() {println(i)}()}
}

或者是通过函数参数传入 i 。

func main() {for i := 0; i < 5; i++ {defer func(i int) {println(i)}(i)}
}

3.在循环内部执行defer语句会发生啥

defer 在函数退出时才能执行,在 for 执行 defer 会导致资源延迟释放。

func main() {for i := 0; i < 5; i++ {func() {f, err := os.Open("/path/to/file")if err != nil {log.Fatal(err)}defer f.Close()}()}
}

unc 是一个局部函数,在局部函数里面执行 defer 将不会有问题。

4.说出一个避免Goroutine泄露的措施

可以通过 context 包来避免内存泄漏。

func main() {ctx, cancel := context.WithCancel(context.Background())ch := func(ctx context.Context) <-chan int {ch := make(chan int)go func() {for i := 0; ; i++ {select {case <- ctx.Done():returncase ch <- i:}}} ()return ch}(ctx)for v := range ch {fmt.Println(v)if v == 5 {cancel()break}}
}

下面的 for 循环停止取数据时,就用 cancel 函数,让另一个协程停止写数据。如果下面 for 已停止读取数据,上面 for 循环还在写入,就会造成内存泄漏。

5.如何跳出for select 循环

通常在for循环中,使用break可以跳出循环,但是注意在go语言中,for select配合时,break 并不能跳出循环。

func testSelectFor2(chExit chan bool){EXIT:for  {select {case v, ok := <-chExit:if !ok {fmt.Println("close channel 2", v)break EXIT//goto EXIT2}fmt.Println("ch2 val =", v)}}//EXIT2:fmt.Println("exit testSelectFor2")
}

6.如何在切片中查找

go中使用 sort.searchXXX 方法,在排序好的切片中查找指定的方法,但是其返回是对应的查找元素不存在时,待插入的位置下标(元素插入在返回下标前)。

可以通过封装如下函数,达到目的。

func IsExist(s []string, t string) (int, bool) {iIndex := sort.SearchStrings(s, t)bExist := iIndex!=len(s) && s[iIndex]==treturn iIndex, bExist
}

7.如何初始化带嵌套结构的结构体

go 的哲学是组合优于继承,使用 struct 嵌套即可完成组合,内嵌的结构体属性就像外层结构的属性即可,可以直接调用。
注意初始化外层结构体时,必须指定内嵌结构体名称的结构体初始化,如下看到 s1方式报错,s2 方式正确。

type stPeople struct {Gender boolName string
}type stStudent struct {stPeopleClass int
}//尝试4 嵌套结构的初始化表达式
//var s1 = stStudent{false, "JimWen", 3}
var s2 = stStudent{stPeople{false, "JimWen"}, 3}
fmt.Println(s2.Gender, s2.Name, s2.Class)

8.切片和数组的区别

数组是具有固定长度,且拥有零个或者多个,相同数据类型元素的序列。数组的长度是数组类型的一部分,所以[3]int 和 [4]int 是两种不同的数组类型。数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变;数组是值传递。数组是内置类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。在初始化后长度是固定的,无法修改其长度。
当作为方法的参数传入时将复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度。数组定义:

var array [10]intvar array =[5]int{1,2,3,4,5}

9.new和make的区别

new 的作用是初始化一个指向类型的指针 (*T) 。new 函数是内建函数,函数定义:func new(Type) Type。使用 new 函数来分配空间。传递给 new 函数的是一个类型,不是一个值。返回值是指向这个新分配的零值的指针。
make 的作用是为 slice,map 或 chan 初始化并返回引用 (T)。make 函数是内建函数,函数定义:func make(Type, size IntegerType) Type;第一个参数是一个类型,第二个参数是长度;返回值是一个类型。
make(T, args) 函数的目的与 new(T) 不同。它仅仅用于创建 Slice, Map 和 Channel,并且返回类型是 T(不是T)的一个初始化的(不是零值)的实例。

10.Printf()、Sprintf()、Fprintf()函数的区别用法是什么

都是把格式好的字符串输出,只是输出的目标不一样。
Printf(),是把格式字符串输出到标准输出(一般是屏幕,可以重定向)。Printf() 是和标准输出文件 (stdout) 关联的,Fprintf 则没有这个限制。
Sprintf(),是把格式字符串输出到指定字符串中,所以参数比printf多一个char*。那就是目标字符串地址。
Fprintf(),是把格式字符串输出到指定文件设备中,所以参数比 printf 多一个文件指针 FILE*。主要用于文件操作。Fprintf() 是格式化输出到一个stream,通常是到文件。

http://www.dtcms.com/a/266829.html

相关文章:

  • MySQL 事务详解:从基础操作到隔离级别与 MVCC 原理
  • vue3引入海康监控视频组件并实现非分屏需求一个页面同时预览多个监控视频;
  • 本地部署项目文档管理网站 MkDocs 并实现外部访问
  • Centos安装Jenkins
  • ZigBee通信技术全解析:从协议栈到底层实现,全方位解读物联网核心无线技术
  • OpenCV 图像操作:颜色识别、替换与水印添加
  • 传统架构开发VS PREEvision:一场效率与可靠性的降维打击
  • [C/C++内存安全]_[中级]_[如何避免数组访问越界]
  • 【精华】QPS限流等场景,Redis其他数据结构优劣势对比
  • 7.4_面试_JAVA_
  • python学习打卡:DAY 18 推断聚类后簇的类型
  • 在 Vue 3 中全局使用 Suspense 组件
  • 【内存】Linux 内核优化实战 - kernel.numa_balancing
  • [Linux]内核态与用户态详解
  • 1.1_3_2 三种交换方式的性能分析
  • PHP从字符串到数值的类型转换
  • 后端密码加密:守护用户数据的钢铁长城
  • 第三章 基于rtthread标准库的串口和shell应用
  • vue 循环无限滚动表格
  • 用distance_transform 检测线性凸包
  • Java项目:基于SSM框架实现的忘忧小区物业管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告】
  • 双因子认证(2FA)是什么?从零设计一个安全的双因子登录接口
  • Linux-进程概念(3)
  • 在HP暗影精灵Ubuntu20.04上修复IntelAX211Wi-Fi不可用的全过程记录——系统安装以后没有WIFI图标无法使用无线网
  • RabbitMQ 高级特性之 TTL
  • Spring Boot 应用启动时,端口 8080 已被其他进程占用,怎么办
  • 物联网中的Unity/Unreal引擎集成:数字孪生与可视化控制
  • 【Spring Boot】HikariCP 与 Druid 连接池全面对比
  • OpenCV中超分辨率(Super Resolution)模块类cv::dnn_superres::DnnSuperResImpl
  • 数字工厂的核心引擎:物联网驱动生产智能化升级