代码之家  ›  专栏  ›  技术社区  ›  Utkarsh Mani Tripathi

在打印语句中,没有7、-48…等,有没有办法以漂亮的方式显示输出?

  •  0
  • Utkarsh Mani Tripathi  · 技术社区  · 8 年前

    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)
    
    2 回复  |  直到 8 年前
        1
  •  3
  •   icza    8 年前

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

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

    type KeyValue struct {
        Key   string
        Value interface{}
    }
    

    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() 现在我们可以找到最大键长度和最大值长度。注意,a的长度 一串 len(s) ,因为它返回UTF-8编码中的字节长度(这是Go在内存中存储字符串的方式)。而是获取字符数(或者更准确地说是 rune s) ,我们使用 utf8.RuneCountInString() .

    - 在右对齐的情况下签名。获取空字符串 "" "-" 在右图中,对于紧凑代码,我使用了一个简单的映射:

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

    使用索引此地图 false 给出映射的值类型的零值,即 ,并使用 true 将给出相关值,即 "-"

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

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

    请注意 %

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

        2
  •  -2
  •   Utkarsh Mani Tripathi    8 年前

    谢谢@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
    

    这是链接 The Go Playground