golang的常见错误,时常看、打基础

49 阅读1分钟

泛型

方法中不能使用泛型

service/history/history.go:43:44: syntax error: method must have no type parameters

image.png

时间

格式化打印毫秒

time.Now().Format("2006-01-02 15:04:05.000")

转义

fmt.Sprintf 输出%

`fmt.Sprintf` 使用 `%%` 来输出 `%` 符号

struct

不能直接修改struct的map类型字段

错误

image.png

正确修改struct的map字段key,而不是直接修改map

image.png

协程中的异常处理


client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true, // 忽略证书有效性验证,只为获取证书信息
			},
		},
	}

	for _, domain := range domainName {
		wg.Add(1)

		go func(domain string) {
                        defer wg.Done()
                        
			resp, err := client.Get("https://" + domain)
			if err != nil {
				fmt.Printf("Error: %v\n", err)
				return
			}
			defer resp.Body.Close()

			// 获取服务器的 TLS 信息
			connectionState := resp.TLS
			if connectionState == nil {
				fmt.Println("No certificates found")
			} else {
				// 获取第一个证书
				cert = connectionState.PeerCertificates[0]
			}

			fmt.Printf("%v 证书过期时间: %v\n", domain, cert.NotAfter)

			PeerCertificates[domain] = cert
			
		}(domain)

	}

这里当err不为Nil时, 如果不return,执行resp.Body.Close()空指针

  • 因为当resp异常时,resp.Body必定为Nil;这时不需要显式调用close方法、关闭响应体

其次,需要确保协程内不发生panic或者空指针等严重错误,如果没有defer wg.Done()时,主协程一直等待;

  • WaitGroup 就不会知道这个协程已经完成,因此 wg.Wait() 将会一直阻塞,等待协程报告完成

标准的做法,确保 defer wg.Done()在协程内其他defer 之前

  • defer 语句可以保证即使在发生 panic 的情况下,仍然能执行 wg.Done(),从而避免阻塞等待的协程永远等待