Golang新手关于fmt.Println的疑问

Golang新手关于fmt.Println的疑问 你好——这是一个完全新手的问题。为什么当我运行下面的代码时,控制台只输出了“Failed to ping…”这条信息?

func main() {
	url := "abc.com"
	timeout := time.Second * 3
	pingTicker := time.NewTicker(30 * time.Second)
	for {
		select {
			case <-pingTicker.C:
				success := ping(url, timeout)
				if !success {
					pingTicker.Stop()
					fmt.Println("Failed to ping...")
					return
				}
			}
	}
	fmt.Println("Process terminated")
}

更多关于Golang新手关于fmt.Println的疑问的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

感谢两位!我感觉自己有点傻——不知为何,我原以为for循环中的return语句有别的含义。

更多关于Golang新手关于fmt.Println的疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


请注意,在进程执行您提到的那行代码(fmt.Println("Failed to ping..."))之后,它会从函数中返回(下一行是 return),这意味着 main() 函数结束——因此不会再执行其他任何代码。

是的,如果你需要从“for”循环中跳出,就需要这样做,否则你会得到一个错误,或者在某些情况下,你会永远等待下去。

无法 ping 通… 致命错误:所有 goroutine 都已休眠 - 死锁!

package main

import (
	"fmt"
	"time"
)

func main() {
	url := "abc.com"
	timeout := time.Second * 3
	pingTicker := time.NewTicker(1 * time.Second)

loop:
	for {
		select {
			case <-pingTicker.C:
				success := ping(url, timeout)
				if !success {
					pingTicker.Stop()
					fmt.Println("Failed to ping...")
					break loop
				}
			}
	}

	fmt.Println("Process terminated")
}

func ping(u string, t time.Duration) bool {
  return false
}

你的代码中,fmt.Println("Process terminated") 永远不会执行,因为 return 语句已经结束了 main 函数的执行。当 ping 函数返回 false 时,会执行 pingTicker.Stop() 停止定时器,然后打印 "Failed to ping...",接着 return 直接退出 main 函数,导致循环外的 fmt.Println("Process terminated") 被跳过。

如果你希望看到 "Process terminated",可以将 return 改为 break 来跳出循环,这样循环外的代码就能执行。例如:

func main() {
    url := "abc.com"
    timeout := time.Second * 3
    pingTicker := time.NewTicker(30 * time.Second)
    for {
        select {
        case <-pingTicker.C:
            success := ping(url, timeout)
            if !success {
                pingTicker.Stop()
                fmt.Println("Failed to ping...")
                break // 改为 break 跳出循环
            }
        }
    }
    fmt.Println("Process terminated") // 现在这行会执行
}

但注意,上面的 break 只会跳出 select 语句,不会跳出外层的 for 循环,所以你需要使用标签来跳出整个循环。修正如下:

func main() {
    url := "abc.com"
    timeout := time.Second * 3
    pingTicker := time.NewTicker(30 * time.Second)
loop:
    for {
        select {
        case <-pingTicker.C:
            success := ping(url, timeout)
            if !success {
                pingTicker.Stop()
                fmt.Println("Failed to ping...")
                break loop // 跳出标签指定的循环
            }
        }
    }
    fmt.Println("Process terminated") // 现在这行会执行
}

这样,当 ping 失败时,会先打印 "Failed to ping...",然后跳出循环,接着执行 fmt.Println("Process terminated")

回到顶部