Go循环for,goto,defer的使用

本文通过示例介绍了Go语言中的for循环和goto语句的用法,并详细解释了defer关键字如何实现延时执行的功能。

如果循环没有达到条件,就会一直会循环。
for循环例子

/*for循环*/
package main

import (
	"fmt"
	"time"
)

func main() {
	//条件循环
	for i := 1; i < 10; i++ {
		fmt.Println(i)
	}

	//条件循环
	num := 1
	for num < 10 {
		num++
		fmt.Println(num)
	}
	//循环一次退出
	for{
		fmt.Println("我爱学习!")
		//睡眠时间
		time.Sleep(500*time.Millisecond)
		break
	}
}

goto循环

/*goto循环*/
package main

import "fmt"

func main() {
	fmt.Println("1")
	goto gameover
	fmt.Println("2")
	return
gameover:
	fmt.Println("3")
}
//1,3,2

多个goto使用循环

/*goto循环*/
package main

import "fmt"

func main() {
	fmt.Println("1")
	goto gameover
	lastword:
	fmt.Println("2")
	return
	gameover:
	fmt.Println("3")
	goto lastword
}
//1,3,2

defer延时执行一个操作

/*延时一个操作*/
package main

import "fmt"

func main() {
	defer fmt.Println("3")

	fmt.Println("1")
	fmt.Println("2")
	//写于不写无所谓
	return
}
//1,2,3

defer延时执行一个函数

/*延时一个函数*/
package main

import "fmt"

func last()  {
	fmt.Println("3")
	fmt.Println("4")
	
}
func main() {
	//延时执行一个函数
	defer last()

	fmt.Println("1")
	fmt.Println("2")
	//写于不写无所谓
	return
}
//1,2,3,4

defer延时执行一个匿名函数

/*延时一个匿名函数*/
package main

import "fmt"

func main() {
	//延时执行一个匿名函数
	defer func() {
		fmt.Println("3")
		fmt.Println("4")
	}()

	fmt.Println("1")
	fmt.Println("2")
	//写于不写无所谓
	return
}
//1,2,3,4

多个defer延时执行

/*多个defer应用*/
package main

import "fmt"

func main() {
	fmt.Println("1")
	defer fmt.Println("4")
	fmt.Println("2")
	defer fmt.Println("3")
}
//1,2,3,4
<think>在编程中,`goto`语句允许程序跳转到代码中标记的位置。尽管它可能导致代码结构混乱(“面条代码”),但在某些场景下合理使用可以提高效率。以下是`goto`的主要使用规范: ### 1. **避免滥用** - **禁止**:用`goto`替代循环或函数调用,导致逻辑混乱 - **允许**:在特定场景集中处理错误恢复或资源清理 ### 2. **作用域限制** - C/C++中`goto`不能跨函数跳转 - 标签必须在同一函数内且位于`goto`之前(部分语言允许向前跳转) ### 3. **资源清理场景** 在需要统一释放资源(如文件句柄、内存)时,使用`goto`集中处理: ```c int func() { FILE *f1 = fopen("a.txt", "r"); if (!f1) return -1; FILE *f2 = fopen("b.txt", "r"); if (!f2) goto cleanup_f1; // 失败时跳转到清理f1 // ...正常逻辑... fclose(f2); cleanup_f1: fclose(f1); return 0; } ``` ### 4. **错误处理** 在多层嵌套中替代重复的`if-return`: ```c int init_system() { if (init_A() != 0) goto fail; if (init_B() != 0) goto fail_A; if (init_C() != 0) goto fail_B; return 0; // 成功 fail_C: deinit_C(); fail_B: deinit_B(); fail_A: deinit_A(); fail: return -1; } ``` ### 5. **跳出多重循环** 当需要从嵌套循环直接退出时(比`flag+break`高效): ```c for (int i=0; i<10; i++) { for (int j=0; j<10; j++) { if (condition) goto end_loop; } } end_loop: // 后续代码 ``` ### 6. **语言差异** - **C/C++**:允许但需谨慎 - **Java/Python**:不支持`goto`(Java保留关键字但禁用) - **Go**:有专门设计的`goto`,要求标签必须先声明 ### 最佳实践 - 将`goto`标签统一放在函数末尾 - 标签命名使用`fail_xxx`、`cleanup_xxx`等明确含义 - 单函数内`goto`跳转方向尽量**向下**(避免回溯导致逻辑复杂) §§相关问题§§ 1. 在哪些编程语言中完全禁止使用`goto`语句?为什么? 2. 如何在不使用`goto`的情况下实现多层嵌套的错误处理? 3. `goto`语句在Linux内核代码中的典型应用场景是什么? 4. 为什么`goto`在资源清理(如文件关闭)中比多次返回(return)更安全? 5. 现代编程语言(如Rust)如何处理`goto`带来的控制流问题?</think>在编程中使用 `goto` 语句需要严格遵循规范,以避免产生"面条代码"(spaghetti code)。以下是主要使用规范: ### 一、允许使用场景 ✅ 1. **集中错误处理**(最佳实践) 在函数退出前统一释放资源: ```c int process_file() { FILE *f1 = fopen("a.txt", "r"); if (!f1) goto error; FILE *f2 = fopen("b.txt", "r"); if (!f2) goto clean_f1; // 失败时跳转到清理点 // ...处理逻辑... fclose(f2); clean_f1: fclose(f1); return 0; error: return -1; } ``` 2. **跳出深层嵌套** 替代多层 `break`: ```c for (int i=0; i<10; i++) { for (int j=0; j<10; j++) { if (error_condition) goto cleanup; // 直接跳出多重循环 } } cleanup: // 清理代码 ``` ### 二、禁止使用场景 ❌ 1. **向前跳转**(除错误处理外) ```c // 禁止:导致逻辑混乱 goto SKIP; x = 10; // 被跳过的代码 SKIP: ``` 2. **跨函数跳转** C语言禁止在不同函数间使用 `goto` 3. **替代循环结构** 禁止用 `goto` 实现循环逻辑(应使用 `for/while`) ### 三、强制规范 1. **标签命名规范** - 错误处理:`error`/`fail` 前缀(`error_open`, `fail_init`) - 资源清理:`cleanup`/`release` 前缀 - 禁用无意义标签(如 `label1`) 2. **作用域限制** - 所有跳转必须在同一函数内 - 避免跳过变量初始化: ```c goto skip; // 错误!跳过初始化 int x = 10; skip: printf("%d", x); // 未初始化 ``` 3. **使用原则** - Linux内核规范:每个函数最多1个 `goto` 出口 - 谷歌C++规范:仅允许用于资源清理 - 微软规范:禁用向前跳转 ### 四、替代方案 1. 使用 `do {...} while(0)` 模拟清理块 2. 利用RAII(C++)或 `defer`(Go/Rust) 3. 函数拆分减少嵌套层级 > **权威参考**:Linux内核代码规范明确要求 `goto` 仅用于错误处理,且必须向下跳转(见 [kernel.org/doc/html/latest/process/coding-style.html](https://www.kernel.org/doc/html/latest/process/coding-style.html))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值