有什么方法可以在打印语句中没有 7、-48 .... 等的情况下以漂亮的方式显示输出?

Is there any way to show the output in pretty way without 7, -48 .... etc in print statements?

代码如下

fmt.Printf("%7s: %-48s\n", "IQN", annotations.Iqn)
fmt.Printf("%7s: %-16s\n", "Volume", args[0])
fmt.Printf("%7s: %-15s\n", "Portal", annotations.TargetPortal)
fmt.Printf("%7s: %-6s\n\n", "Size", annotations.VolSize)

没有,没有。

但是你可以编写一个实用函数来自动执行所有这些操作,你需要做的就是传递你想要漂亮打印的键值对。

让我们用这种类型对键值建模:

type KeyValue struct {
    Key   string
    Value interface{}
}

请注意,值可以是任何类型,而不仅仅是 string 值。我们将在打印时使用默认格式。如果您想要默认格式以外的格式,您可以随时将其转换为您喜欢的 string,并将其设置为值。

漂亮打印实用函数(解释如下):

var aligns = map[bool]string{true: "-"}

func printKeyValues(keyRight, valueRight bool, kvs ...KeyValue) {
    // First convert values to string and find max key and max value lengths:
    values := make([]string, len(kvs))
    maxKey, maxValue := 0, 0
    for i, kv := range kvs {
        if length := utf8.RuneCountInString(kv.Key); length > maxKey {
            maxKey = length
        }
        values[i] = fmt.Sprint(kv.Value)
        if length := utf8.RuneCountInString(values[i]); length > maxValue {
            maxValue = length
        }
    }

    // Generate format string:
    fs := fmt.Sprintf("%%%s%ds: %%%s%ds|\n",
        aligns[keyRight], maxKey+1, aligns[valueRight], maxValue+1)

    // And now print the key-values:
    for i, kv := range kvs {
        fmt.Printf(fs, kv.Key, values[i])
    }
}

正在测试:

printKeyValues(false, true, []KeyValue{
    {"IQN", "asdfl;kj"},
    {"Volume", "asdf;lkjasdf"},
    {"Portal", "asdf"},
    {"Size", 12345678},
}...)

输出:

    IQN: asdfl;kj     |
 Volume: asdf;lkjasdf |
 Portal: asdf         |
   Size: 12345678     |

另一个测试:

printKeyValues(true, false, []KeyValue{
    {"IQN", "asdfl;kj"},
    {"Volume", "asdf;lkjasdf"},
    {"Portal", "asdf"},
    {"Size", 12345678},
}...)

输出:

IQN    :      asdfl;kj|
Volume :  asdf;lkjasdf|
Portal :          asdf|
Size   :      12345678|

尝试 Go Playground 上的示例。

说明

printKeyValues() 首先遍历键值对,然后通过调用 fmt.Sprint(). Now we can find the max key length and the max value length. Note that length of a string is not len(s), as that returns the byte-length in UTF-8 encoding (which is how Go stores strings in memory). Instead to get the number of characters (or more precisely the number of runes), we used utf8.RuneCountInString().

使用默认格式将值转换为 string

一旦有了这个,我们就可以生成使用最大键长度和最大值长度的格式字符串。我们还将提供控制是否要将键和值左对齐或右对齐的可能性,在格式字符串中,这意味着 - 符号在右对齐的情况下。为了在左边的情况下得到一个空字符串 "",在右边的情况下得到一个 "-",为了紧凑的代码,我使用了一个简单的映射:

var aligns = map[bool]string{true: "-"}

使用 false 索引此映射给出映射值类型的零值,即 "",使用 true 索引将给出关联值 [= =29=]。由于这张地图总是一样的,我把它移到了函数之外(小优化)。

为了生成我们使用的格式字符串 fmt.Sprintf():

fs := fmt.Sprintf("%%%s%ds: %%%s%ds|\n",
    aligns[keyRight], maxKey+1, aligns[valueRight], maxValue+1)

请注意,% 符号需要加倍,因为这在格式字符串中很特殊。

还有最后一项任务:使用生成的格式字符串打印所有键值对。

谢谢@icza,我找到了另一种方法,看看这个:-)

package main

import (
  "text/template"
  "os"
)

func main() {
   type Annotations struct {
     IQN    string
     Volume string
     Portal string
     Size   string
   }
   annotation := Annotations{

     IQN: "openebs.io",
     Volume: "vol",
     Portal: "10.29.1.1:3260",
     Size: "1G",

   }
   tmpl, err := template.New("test").Parse("IQN     : 
{{.IQN}}\nVolume  : {{.Volume}}\nPortal  : {{.Portal}}\nSize    : 
{{.Size}}")
   if err != nil {
        panic(err)
    }
  err = tmpl.Execute(os.Stdout, annotation)
  if err != nil {
        panic(err)
  }
}

输出:

IQN     : openebs.io
Volume  : vol
Portal  : 10.29.1.1:3260
Size    : 1G

这里是linkThe Go Playground