package mainimport "fmt"func main() {// 创建一个长度为3,容量为5的整数切片var numbers = make([]int, 3, 8)// 打印初始状态printSlice(numbers) // 输出: len=3 cap=5 slice=[0 0 0]// 向切片添加元素numbers = append(numbers, 1, 2)// 再次打印,观察长度和容量的变化printSlice(numbers) // 输出: len=5 cap=5 slice=[0 0 0 1 2]// 再添加一个元素,超出原有容量numbers = append(numbers, 3)// 再次打印,观察容量的变化printSlice(numbers) // 输出: len=6 cap=10 slice=[0 0 0 1 2 3]/* 创建切片 numbers1 是之前切片的两倍容量*/numbers1 := make([]int, len(numbers), (cap(numbers))*2)/* 拷贝 numbers 的内容到 numbers1 */copy(numbers1,numbers)printSlice(numbers1) /* 打印子切片从索引 2(包含) 到索引 5(不包含) */number3 := numbers[2:4]printSlice(number3)// 尝试访问超出切片范围的索引,这可能会导致 panic// 使用匿名函数和 defer 来处理可能的 panicfunc() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()// 尝试访问超出切片范围的索引number4 := numbers[2:100]printSlice(number4)}()for i, v := range numbers1 {fmt.Printf("%d = %d\n", i, v)}for i, c := range "hello" {fmt.Printf("index: %d, char: %c\n", i, c)}map1 := make(map[int]float32)// 向 map1 中添加 key-value 对map1[1] = 1.0map1[2] = 2.0map1[3] = 3.0map1[4] = 4.0// 遍历 map1,读取 key 和 valuefor key, value := range map1 {// 打印 key 和 valuefmt.Printf("key is: %d - value is: %f\n", key, value)}// 遍历 map1,只读取 keyfor key := range map1 {// 打印 keyfmt.Printf("key is: %d\n", key)}// 遍历 map1,只读取 valuefor _, value := range map1 {// 打印 valuefmt.Printf("value is: %f\n", value)}}// printSlice 函数用于打印切片的长度、容量和内容
func printSlice(x []int) {fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
其中加入异常的说明:
你的观察是正确的。在 Go 中,尝试访问超出切片范围的索引确实会导致 panic。为了处理这种情况,我们可以使用 Go 的 recover
机制来捕获 panic。以下是如何修改代码以添加异常处理:
package mainimport ("fmt"
)func main() {// ... 前面的代码保持不变 .../* 打印子切片从索引 2(包含) 到索引 4(不包含) */number3 := numbers[2:4]printSlice(number3)// 使用匿名函数和 defer 来处理可能的 panicfunc() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered from panic:", r)}}()// 尝试访问超出切片范围的索引number4 := numbers[2:100]printSlice(number4)}()fmt.Println("程序继续执行...")
}// printSlice 函数保持不变
func printSlice(x []int) {fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
解释:
- 我们将可能导致 panic 的代码包装在一个匿名函数中。
- 使用
defer
语句和另一个匿名函数来设置 panic 恢复机制。 - 在 defer 的函数中,我们使用
recover()
来捕获可能发生的 panic。 - 如果发生 panic,程序会打印出错误信息,但不会终止执行。
- 最后,我们添加了一条打印语句来显示程序继续执行。
这种方法允许我们优雅地处理潜在的 panic,而不会导致整个程序崩溃。请注意,虽然这种方法可以防止程序崩溃,但在实际应用中,我们通常应该避免访问超出切片范围的索引,而是通过适当的边界检查来预防这种情况的发生。
在生产环境中,你可能还想记录这个错误,或者根据你的应用需求采取其他适当的措施。