golang tabwriter格式不正确
我正在遵循关于go的常见规则 其中,相关写入程序被初始化并用于将格式化输出打印到标准输出 以下是我的代码片段: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)
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")
}