繁体   English   中英

golang tabwriter 格式不正确

[英]golang tabwriter does not format appropriately

我正在遵循关于gotabwriter的常见模式

其中相关的 writer 被初始化并用于将格式化的输出打印到 stdout。

这是我的代码片段:

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

为什么每列不保持固定宽度(我假设基于相关作者的初始化应该是 30 个字符长?)。 上面代码中的错误配置在哪里?

编辑

我所期望的是,每一列都有一个固定的,即第二列(节点数)总是出现在与

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

问题是您像这样初始化制表符:

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

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

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

展望未来:在集群循环中,您应该使用换行符,因为虽然在您的示例中每个项目只有一个集群,但如果您有更多,它们将打印在一行中。

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

好的,让我们看看您的示例,更改为可在 Go Playground 上运行。 我将使用以下测试数据:

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")
}

然后输出(在Go Playground上尝试):

---------------------------------------------------------
Project p1
---------------------------------------------------------
             Cluster|          Node Count|
                p1c1|                   2|
                p1c2|                   3|

---------------------------------------------------------
Project p2
---------------------------------------------------------
             Cluster|          Node Count|
                p2c1|                   4|
                p2c2|                   5|

混合“常规” 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 的情况下打印相同的内容(在Go Playground上尝试)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM