Golang vet工具生成的JSON代码无效问题探讨

Golang vet工具生成的JSON代码无效问题探讨 运行 go vet -json .\cmd\factoryinput\ 会输出以下字符串:

# github.com/united-manufacturing-hub/united-manufacturing-hub/cmd/factoryinput
{}

将此字符串传入 json.loads (Python)、jsonformatter.curiousconcept.comjsonlint.com 或 jq 都会导致它们报错。

同时,查阅 ECMA-404 (https://www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf) 也未显示 # 是有效的 JSON 字符。

系统信息

  • go version go1.17.6 windows/amd64
  • jq - commandline JSON processor [version 1.6]
  • Python 3.10.0
  • Windows 11 (Version 21H2) (OS Build 22000.376)

(抱歉 jsonlint.com 链接中有空格,但我只被允许插入 2 个链接)


更多关于Golang vet工具生成的JSON代码无效问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang vet工具生成的JSON代码无效问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go vet -json 的输出格式是每行一个独立的 JSON 对象,以换行符分隔。开头的 # 行是标准错误输出(stderr)的诊断信息,不是 JSON 的一部分。你需要分离标准输出(stdout)和标准错误输出(stderr),并仅处理标准输出中的 JSON 内容。

以下是处理该问题的正确方法:

1. 分离标准输出和标准错误输出:

# 将标准错误输出重定向到文件,只捕获标准输出的 JSON
go vet -json .\cmd\factoryinput\ 2> vet_errors.txt > vet_output.json

# 或者将标准错误输出重定向到 /dev/null(Linux/Mac)
go vet -json .\cmd\factoryinput\ 2>/dev/null > vet_output.json

# Windows PowerShell
go vet -json .\cmd\factoryinput\ 2>$null > vet_output.json

2. 直接通过管道处理标准输出:

# 使用 jq 处理(自动忽略非 JSON 行)
go vet -json .\cmd\factoryinput\ 2>/dev/null | jq .

# 或者使用 grep 过滤掉以 # 开头的行
go vet -json .\cmd\factoryinput\ 2>&1 | grep -v '^#' | jq .

3. Go 代码示例解析输出:

package main

import (
    "encoding/json"
    "fmt"
    "os/exec"
    "strings"
)

func main() {
    cmd := exec.Command("go", "vet", "-json", "./cmd/factoryinput/")
    output, err := cmd.CombinedOutput()
    if err != nil {
        // 忽略退出状态错误,因为 vet 可能返回非零状态
    }
    
    lines := strings.Split(string(output), "\n")
    for _, line := range lines {
        line = strings.TrimSpace(line)
        if line == "" || strings.HasPrefix(line, "#") {
            continue // 跳过注释行和空行
        }
        
        var result map[string]interface{}
        if err := json.Unmarshal([]byte(line), &result); err == nil {
            fmt.Printf("有效 JSON: %v\n", result)
        }
    }
}

4. Python 示例解析输出:

import subprocess
import json

result = subprocess.run(
    ["go", "vet", "-json", "./cmd/factoryinput/"],
    capture_output=True,
    text=True
)

# 处理每行输出
for line in result.stdout.splitlines():
    line = line.strip()
    if not line or line.startswith("#"):
        continue
    try:
        data = json.loads(line)
        print(f"有效 JSON: {data}")
    except json.JSONDecodeError:
        continue

# 错误输出(包含 # 开头的行)
print("错误输出:", result.stderr)

关键点说明:

  • # 开头的行是诊断信息,输出到标准错误输出(stderr)
  • 每行有效的 JSON 对应一个检查结果(可能有多行)
  • 空 JSON 对象 {} 表示该包通过了所有 vet 检查
  • 需要逐行解析输出,跳过非 JSON 行

这样处理就能正确解析 go vet -json 的输出,避免因 # 注释行导致的 JSON 解析错误。

回到顶部