为了账号安全,请及时绑定邮箱和手机立即绑定

golang tabwriter 格式不正确

golang tabwriter 格式不正确

Go
慕莱坞森 2023-08-14 15:12:21
我遵循关于 的常见模式gotabwriter其中相关编写器被初始化并用于将格式化输出打印到标准输出。这是我的代码片段: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 Countmy-cluster-1  3---------------------------------------------------------Project my-project-2---------------------------------------------------------Cluster         Node Countmy-newest-project-1       2---------------------------------------------------------Project my-project-3---------------------------------------------------------Cluster         Node Countanothercluster 1为什么每列不保持固定宽度(我认为根据相关编写器的初始化应该是 30 个字符长?)。上面的代码哪里配置错误了?编辑:我期望的是,每一列都有一个固定的,即第二列(节点数)始终出现在与中相同的位置(列)中Project my-project-1---------------------------------------------------------Cluster         Node Countmy-cluster-1              3---------------------------------------------------------Project my-project-2---------------------------------------------------------Cluster          Node Countmy-newest-project-1       2---------------------------------------------------------Project my-project-3---------------------------------------------------------Cluster         Node Countanothercluster           1
查看完整描述

1 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

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


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

第二个参数是最小单元格宽度:20,第三个参数是制表符宽度:30。这应该对应于打印制表符宽度的值。大多数系统使用 4 或 8 宽度来打印标签。下一个参数告诉我们使用制表符进行对齐。在这种情况下,制表符假设 1 个打印的制表符占用 30 个空格(这就是前面的参数所说的),这会导致计算不准确。

通过使用空格而不是制表符进行填充可以简单地消除此问题。


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


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


提示:您可以使用tabwriter.Debugflag 来打印单元格边框。


好的,让我们看看您的示例,已更改为可在 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,两者都打印到标准输出。


另请注意,制表符可以轻松地替换为简单的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上尝试一下)。



查看完整回答
反对 回复 2023-08-14
  • 1 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信