golang tabwriter格式不正确

golang tabwriter格式不正确,go,Go,我正在遵循关于go的常见规则 其中,相关写入程序被初始化并用于将格式化输出打印到标准输出 以下是我的代码片段: w := tabwriter.NewWriter(os.Stdout, 20, 30, 1, '\t', tabwriter.AlignRight) for _, v := range listProjectsResponse.Projects { parent := fmt.Sprintf("projects/%s/locations/-", v.ProjectId)

我正在遵循关于go的常见规则

其中,相关写入程序被初始化并用于将格式化输出打印到标准输出

以下是我的代码片段:

w := tabwriter.NewWriter(os.Stdout, 20, 30, 1, '\t', tabwriter.AlignRight)


for _, v := range listProjectsResponse.Projects {
    parent := fmt.Sprintf("projects/%s/locations/-", v.ProjectId)
    resp, err := containerService.Projects.Locations.Clusters.List(parent).Do()
    if err != nil {
        log.Fatalf(err.Error())
    }
    if len(resp.Clusters) > 0 {
        fmt.Println("---------------------------------------------------------")
        fmt.Printf("Project\t%s\n", v.ProjectId)
        fmt.Println("---------------------------------------------------------")
        fmt.Fprintf(w, "Cluster\t\tNode Count\n")
        //w.Flush()
        for _, p := range resp.Clusters {
            fmt.Fprintf(w, "%s\t%d\t", p.Name, p.CurrentNodeCount)
            //w.Flush()
        }
        w.Flush()
        fmt.Printf("\n")
    }
}
但是,似乎没有考虑柱之间的公共距离,如以下输出所示:

Project my-project-1
---------------------------------------------------------
Cluster         Node Count
my-cluster-1  3
---------------------------------------------------------
Project my-project-2
---------------------------------------------------------
Cluster         Node Count
my-newest-project-1       2
---------------------------------------------------------
Project my-project-3
---------------------------------------------------------
Cluster         Node Count
anothercluster 1
为什么每一列不保持固定的宽度(根据相关writer的初始化,我假设该宽度应该是30个字符长?)。 上述代码中的错误配置在哪里

编辑

我所期望的是,每列都有一个固定的with,即第二列(节点计数)始终显示在与中相同的位置(列)


问题在于,您可以如下方式初始化tabwriter:

w := tabwriter.NewWriter(os.Stdout, 20, 30, 1, '\t', tabwriter.AlignRight)
第二个参数是最小单元格宽度:
20
,第三个参数是选项卡宽度:
30
。这应该对应于打印选项卡宽度的值。大多数系统使用4或8宽度的打印标签。下一个参数告诉我们使用制表符进行对齐。在这种情况下,tabwriter假设1个打印的选项卡占用30个空格(这是前面的参数所告诉的),这会导致计算不准确。
这个问题可以简单地通过使用空格而不是制表符来填充来消除

下一步:您必须在最后一个单元格之后使用制表符,否则tabwriter将不知道它是单元格的结尾,并且无法使它们正确对齐

继续:在集群循环中,您应该使用换行符,因为尽管在您的示例中,每个项目只有一个集群,但是如果您有更多集群,它们将被打印在一行中

还有一个提示:您可以使用
tabwriter.Debug
标志打印单元格边框

好的,让我们看看你的例子,改为在运动场上运行。我将使用以下测试数据:

type Cluster struct {
    Name             string
    CurrentNodeCount int
}

type Project struct {
    ProjectId string
    Clusters  []Cluster
}

projects := []Project{
    {
        ProjectId: "p1",
        Clusters: []Cluster{
            {Name: "p1c1", CurrentNodeCount: 2},
            {Name: "p1c2", CurrentNodeCount: 3},
        },
    },
    {
        ProjectId: "p2",
        Clusters: []Cluster{
            {Name: "p2c1", CurrentNodeCount: 4},
            {Name: "p2c2", CurrentNodeCount: 5},
        },
    },
}
以及处理/格式化代码:

w := tabwriter.NewWriter(os.Stdout, 20, 8, 1, ' ',
    tabwriter.Debug|tabwriter.AlignRight)

for _, v := range projects {
    if len(v.Clusters) == 0 {
        continue
    }
    fmt.Println("---------------------------------------------------------")
    fmt.Printf("Project\t%s\n", v.ProjectId)
    fmt.Println("---------------------------------------------------------")
    fmt.Fprintf(w, "Cluster\tNode Count\t\n")
    for _, p := range v.Clusters {
        fmt.Fprintf(w, "%s\t%d\t\n", p.Name, p.CurrentNodeCount)
    }
    w.Flush()
    fmt.Printf("\n")
}
然后输出(在上尝试):

混合使用“常规”
fmt
调用和tabwriter可能不是一个好主意,它们都打印到标准输出

还请注意,tabwriter很容易被简单的
fmt
格式化打印所取代:

for _, v := range projects {
    if len(v.Clusters) == 0 {
        continue
    }
    fmt.Println("---------------------------------------------------------")
    fmt.Printf("Project\t%s\n", v.ProjectId)
    fmt.Println("---------------------------------------------------------")
    fmt.Printf("%20s|%20s|\n", "Cluster", "Node Count")
    for _, p := range v.Clusters {
        fmt.Printf("%20s|%20d|\n", p.Name, p.CurrentNodeCount)
    }
    fmt.Printf("\n")
}

以上代码将在不使用tabwriter的情况下打印相同的内容(在上尝试)。

您的预期输出是什么?我已相应地更新了问题
---------------------------------------------------------
Project p1
---------------------------------------------------------
             Cluster|          Node Count|
                p1c1|                   2|
                p1c2|                   3|

---------------------------------------------------------
Project p2
---------------------------------------------------------
             Cluster|          Node Count|
                p2c1|                   4|
                p2c2|                   5|
for _, v := range projects {
    if len(v.Clusters) == 0 {
        continue
    }
    fmt.Println("---------------------------------------------------------")
    fmt.Printf("Project\t%s\n", v.ProjectId)
    fmt.Println("---------------------------------------------------------")
    fmt.Printf("%20s|%20s|\n", "Cluster", "Node Count")
    for _, p := range v.Clusters {
        fmt.Printf("%20s|%20d|\n", p.Name, p.CurrentNodeCount)
    }
    fmt.Printf("\n")
}