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

Golang | 面试题每日一练 (1)

💢欢迎来到张胤尘的技术站
💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥

文章目录

  • Golang | 每日一练 (1)
    • 题目
    • 参考答案

Golang | 每日一练 (1)

题目

golangdefer 语句的执行顺序是如何定义的?请说明 defer 与函数返回值之间的交互机制。

参考答案

golang 中,defer 用于延迟执行函数调用,直到包含它的函数返回时才执行。

defer 语句的执行顺序遵循 后进先出(LIFO) 原则,即最后声明的 defer 会最先执行。

例如:

package main

import "fmt"

func main() {

	// 输出顺序为:
	// main function
	// defer 2
	// defer 1

	defer fmt.Println("defer 1")
	defer fmt.Println("defer 2")
	fmt.Println("main function")
}

由以上代码示例中可以看出,defer 的执行顺序与声明顺序是相反的。

由于 defer 的执行时机在 return 之后,但在返回值被传递给调用者之前。这也就是说 defer 可以修改返回值,具体的修改时机有如下两种情况:

  • 无命名返回值

如果函数的返回值没有命名,defer 无法修改返回值。例如:

package main

import "fmt"

func test() int {
	var i int
	defer func() {
		i++
	}()
	return i
}

func main() {
	ret := test()
	fmt.Println(ret) // 0
}

main 函数中调用了 test 函数并进行结果的输出,观察到输出的结果为0,使用 defer 后并没有修改 i 返回值的结果。

当函数返回值没有命名时,return 会将函数栈中的变量值拷贝到调用栈的临时变量中,然后执行 deferdefer 修改的是函数栈中的变量,而不是调用栈的临时变量。因此,defer 的修改不会影响最终的返回值。

  • 命名返回值

当函数返回值有命名时,情况会有所不同。defer 可以直接修改这个变量的值,最终影响返回值。例如:

package main

import "fmt"

func test() (i int) {
	defer func() {
		i++
	}()
	return i
}

func main() {
	ret := test()
	fmt.Println(ret) // 1
}

golang 中,命名返回值不仅仅是语法糖,它实际上是一个在函数作用域内声明的变量。这意味着命名返回值在函数的整个生命周期内都是可访问和可修改的。

执行流程分析:

  • 当声明一个命名返回值 func test() (i int) 时,golang 会在函数的作用域内声明一个变量 i,并将其初始化为 0int 类型的零值)。

  • golang 中,return 的行为是将命名返回值的当前值标记为要返回的值,但并不会立即返回。此时,命名返回值 i 的值会被“标记”为返回值,但实际的返回操作还没有完成。

  • defer 会在函数返回之前执行,但它的执行时机是在 return 将返回值标记之后,但在实际返回操作完成之前。这意味着 defer 可以访问和修改命名返回值 i

  • defer 中,可以直接修改命名返回值 i,因为 i 是函数作用域内的变量,defer 可以访问和修改它。这种修改会影响最终返回的值。

最终在 defer 执行完成后,函数才会将命名返回值的实际值返回给调用者。因此,defer 中对命名返回值的修改会直接影响最终的返回值。

🌺🌺🌺撒花!

如果本文对你有帮助,就点关注或者留个👍
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。

在这里插入图片描述


http://www.kler.cn/a/551423.html

相关文章:

  • huggingface/pytorch-image-models
  • 二级等保项目设备清单及高风险项整改方向
  • vue3.x的Suspense详细解读
  • CAP与BASE:分布式系统设计的灵魂与妥协
  • Python语言的嵌入式系统
  • ubuntu在线安装PostgreSQL(pgsql)
  • 【从0做项目】Java搜索引擎(5)
  • 奥比中光3D机器视觉相机能连接halcon吗?
  • python学opencv|读取图像(六十六)使用cv2.minEnclosingCircle函数实现图像轮廓圆形标注
  • Spring Boot 的约定优于配置:简化开发的艺术
  • 力扣LeetCode: 1287 有序数组中出现次数超过25%的元素
  • 腾讯云DeepSeek大模型应用搭建指南
  • HTML【详解】input 标签
  • 人工智障的软件开发-git仓库篇-弃gitlab,走gitea
  • React 的 context 是什么?
  • 设计模式--访问者模式【行为型模式】
  • go设置镜像代理
  • 深入解析 vLLM:高性能 LLM 服务框架的架构之美(一)原理与解析
  • Python笔记——零基础学python:超详细的入门教程!python入门教程(非常详细)
  • 【Elasticsearch】词项中心(term-centric)和字段中心(field-centric)