Golang 格式化打印工具 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
rix
V2EX    Go 编程语言

Golang 格式化打印工具

  •  
  •   rix 2022-09-18 01:02:52 +08:00 2348 次点击
    这是一个创建于 1122 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很多候我需要格式化打印出一些的,但是 Golang 自的 "%#v" 格式化不是很好,可定性也不高,而且把很多的私有值都打印出,比如 time.Time

    因此我了可以完全自定,能方便地控制出格式,管理,而且有接口的格式化模:

    gopkg.in/structformat.v0

    比如你有一定:

    type Encryption struct { Key []byte IV []byte Tag []byte Mode string Plaintext string Ciphertext []byte } 

    你想格式化打印一份的:

    enc := &Encryption{ Key: []byte{0xf8,0x0f,0xe1,0xef,0x1b,0x28,0x92,0xe8,0x12,0x0f,0x0d,0x75,0xa1,0xb0,0x67,0xce}, IV: []byte{0xdf,0x3a,0xb2,0x8c,0x39,0xb9,0xa4,0x52,0xce,0xfd,0xd2,0x9d,0x0a,0x02,0xd4,0x1d}, Tag: nil, Mode: "CTR", Plaintext: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et \n" + "dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex \n" + "ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \n" + "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt \n" + "mollit anim id est laborum", Ciphertext: []byte{ 0xa3,0xb1,0x24,0x93,0x30,0x88,0x31,0xdc,0x3d,0x32,0xea,0x7b,0x06,0xbe,0x86,0xba, 0x31,0xe7,0x72,0x5a,0x9c,0x72,0x9c,0xa4,0xea,0x4b,0xa1,0x5f,0x95,0x47,0xad,0xfc, 0x5e,0x40,0x15,0x62,0x4e,0x35,0xe4,0xe5,0xfe,0x53,0x24,0x68,0x8a,0x77,0x0c,0xb7, 0xf9,0x8c,0xac,0x4d,0xdf,0x66,0x64,0x86,0x5a,0xba,0xcc,0xeb,0x68,0x16,0x43,0xd2, 0x84,0x37,0xaf,0x4b,0xe4,0x47,0x2a,0x84,0x1e,0x0a,0x1d,0xff,0x7d,0x76,0x00,0x47, 0xe6,0x51,0x96,0xfa,0x19,0x96,0x1b,0xa9,0x04,0x42,0xcf,0xbc,0xc0,0x88,0x71,0x03, 0xe7,0x49,0x4c,0x0e,0xf5,0x0f,0x1f,0x8c,0x69,0x3e,0x65,0x07,0x90,0x56,0xc7,0xa7, 0xf1,0x95,0xd6,0xb2,0xbb,0xb8,0x3a,0x8e,0x66,0xbc,0x0a,0xbc,0x20,0x79,0xcc,0xa8, 0xa8,0x65,0x23,0x5c,0xcf,0xe9,0x4d,0x76,0x6e,0x13,0xf0,0x64,0x13,0x5a,0x08,0xab, 0xdf,0x90,0x83,0xce,0x01,0x5a,0x5e,0xaa,0x3d,0x0e,0x46,0x76,0x04,0x99,0xe0,0x16, 0xb2,0x76,0xbe,0x28,0x4b,0xe2,0x12,0xf5,0xdc,0x60,0x5b,0x67,0xe6,0xaa,0x2c,0x70, 0x49,0x7e,0x55,0x5c,0x1c,0x0a,0x60,0x36,0x69,0x97,0xf3,0x29,0x04,0x90,0x5f,0x60, 0xd7,0x65,0x60,0xa8,0xc0,0x76,0xd1,0xe3,0x42,0xc1,0x0e,0x63,0xf9,0xe0,0x72,0xec, 0x95,0x97,0x44,0x9c,0xea,0xf3,0x21,0x50,0x5b,0xa7,0x3e,0xde,0xe3,0x8c,0x7d,0xee, 0xcc,0x64,0x74,0x77,0xb5,0xcc,0xdc,0x8e,0xe5,0x97,0x63,0x6b,0x7f,0x56,0x5c,0x5d, 0x7f,0x6f,0x68,0x8b,0x5b,0xa6,0x37,0xe8,0xf5,0xb7,0xfc,0xf9,0x96,0xb6,0xc0,0xb7, 0x17,0x3d,0xd1,0xfe,0x11,0x6d,0x39,0x39,0x37,0xbe,0x1f,0xe7,0x1f,0x13,0x99,0x9f, 0xdb,0x2f,0xcc,0xc8,0x46,0x92,0x85,0x12,0xb0,0x41,0x0a,0x14,0xd1,0x8f,0x46,0xf4, 0x5e,0xac,0x1c,0xf5,0xa7,0x40,0xe1,0xfe,0x51,0xc4,0xe0,0x1a,0x12,0x37,0xee,0x97, 0x63,0x47,0x50,0x4c,0xfa,0x87,0x4b,0xc6,0xe7,0xda,0x31,0x4d,0x13,0x62,0x39,0xb2, 0xfe,0x3a,0xb5,0x96,0x53,0x90,0xd5,0x06,0x8d,0x57,0x22,0x7f,0xc3,0xcd,0x75,0x99, 0xff,0x45,0x51,0x10,0xbc,0x03,0x0b,0xb8,0x82,0x5d,0x77,0xd6,0xb5,0xa2,0x81,0x00, 0xb4,0x78,0xe3,0xd3,0xcd,0xad,0x37,0xf3,0x76,0xf8,0x40,0x2d,0x5e,0xf1,0x17,0x01, 0xd0,0x13,0x4b,0xbe,0x4c,0x7e,0x1d,0x67,0x54,0xd0,0xc6,0x19,0x7a,0x91,0x91,0xc7, 0x5f,0xad,0xd5,0x99,0x4e,0x03,0x79,0x7e,0x86,0x9a,0x38,0xbf,0x12,0x1a,0xa0,0x6e, 0x32,0xb2,0x41,0xda,0x11,0x4e,0xfc,0x3c,0x61,0x5a,0x02,0x95,0x2b,0x6b,0x15,0xc6, 0xa9,0xcd,0xc2,0x56,0xc1,0xc3,0x2a,0x43,0xc6,0xbf,0xfc,0x0b,0x46,0xe8,0xc7,0xee, 0xea,0x64,0x9b,0x08,0x42,0x6a,0x47,0x9d,0x4c,0xce,0xe7,0x95, }, } 

    利用模,你需要型一建打印式的接口。模提供了很多建式的基本函,通拼接合些函就能以明式的方式定式了。模式非常似在格式化日的做法:

    func (enc *Encryption) StructFormat(w sfmt.Writer) (n int, err error) { return sfmt.Struct( `Encryption`, sfmt.KV(`Key`, sfmt.HexBytes(enc.Key)), sfmt.KV(`IV`, sfmt.HexBytes(enc.IV)), sfmt.KV(`Tag`, sfmt.HexBytes(enc.Tag)), sfmt.KV(`Mode`, sfmt.String(enc.Mode)), sfmt.KV(`Plaintext`, sfmt.String(enc.Plaintext), sfmt.KVNewLine()), sfmt.KV(`Ciphertext`, sfmt.Hexdump(enc.Ciphertext), sfmt.KVNewLine()), ).StructFormat(w) } 

    然後在主程序中打印只要:

     sfmt.Format(os.Stdout, enc) 

    最的打印出如下:

    Encryption { Key: 0xf80fe1ef1b2892e8120f0d75a1b067ce IV: 0xdf3ab28c39b9a452cefdd29d0a02d41d Tag: ( EMPTY ) Mode: CTR Plaintext: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum Ciphertext: 00000000 a3 b1 24 93 30 88 31 dc 3d 32 ea 7b 06 be 86 ba |..$.0.1.=2.{....| 00000010 31 e7 72 5a 9c 72 9c a4 ea 4b a1 5f 95 47 ad fc |1.rZ.r...K._.G..| 00000020 5e 40 15 62 4e 35 e4 e5 fe 53 24 68 8a 77 0c b7 |^@.bN5...S$h.w..| 00000030 f9 8c ac 4d df 66 64 86 5a ba cc eb 68 16 43 d2 |...M.fd.Z...h.C.| 00000040 84 37 af 4b e4 47 2a 84 1e 0a 1d ff 7d 76 00 47 |.7.K.G*.....}v.G| 00000050 e6 51 96 fa 19 96 1b a9 04 42 cf bc c0 88 71 03 |.Q.......B....q.| 00000060 e7 49 4c 0e f5 0f 1f 8c 69 3e 65 07 90 56 c7 a7 |.IL.....i>e..V..| 00000070 f1 95 d6 b2 bb b8 3a 8e 66 bc 0a bc 20 79 cc a8 |......:.f... y..| 00000080 a8 65 23 5c cf e9 4d 76 6e 13 f0 64 13 5a 08 ab |.e#\..Mvn..d.Z..| 00000090 df 90 83 ce 01 5a 5e aa 3d 0e 46 76 04 99 e0 16 |.....Z^.=.Fv....| 000000a0 b2 76 be 28 4b e2 12 f5 dc 60 5b 67 e6 aa 2c 70 |.v.(K....`[g..,p| 000000b0 49 7e 55 5c 1c 0a 60 36 69 97 f3 29 04 90 5f 60 |I~U\..`6i..).._`| 000000c0 d7 65 60 a8 c0 76 d1 e3 42 c1 0e 63 f9 e0 72 ec |.e`..v..B..c..r.| 000000d0 95 97 44 9c ea f3 21 50 5b a7 3e de e3 8c 7d ee |..D...!P[.>...}.| 000000e0 cc 64 74 77 b5 cc dc 8e e5 97 63 6b 7f 56 5c 5d |.dtw......ck.V\]| 000000f0 7f 6f 68 8b 5b a6 37 e8 f5 b7 fc f9 96 b6 c0 b7 |.oh.[.7.........| 00000100 17 3d d1 fe 11 6d 39 39 37 be 1f e7 1f 13 99 9f |.=...m997.......| 00000110 db 2f cc c8 46 92 85 12 b0 41 0a 14 d1 8f 46 f4 |./..F....A....F.| 00000120 5e ac 1c f5 a7 40 e1 fe 51 c4 e0 1a 12 37 ee 97 |^[email protected]..| 00000130 63 47 50 4c fa 87 4b c6 e7 da 31 4d 13 62 39 b2 |cGPL..K...1M.b9.| 00000140 fe 3a b5 96 53 90 d5 06 8d 57 22 7f c3 cd 75 99 |.:..S....W"...u.| 00000150 ff 45 51 10 bc 03 0b b8 82 5d 77 d6 b5 a2 81 00 |.EQ......]w.....| 00000160 b4 78 e3 d3 cd ad 37 f3 76 f8 40 2d 5e f1 17 01 |.x....7.v.@-^...| 00000170 d0 13 4b be 4c 7e 1d 67 54 d0 c6 19 7a 91 91 c7 |..K.L~.gT...z...| 00000180 5f ad d5 99 4e 03 79 7e 86 9a 38 bf 12 1a a0 6e |_...N.y~..8....n| 00000190 32 b2 41 da 11 4e fc 3c 61 5a 02 95 2b 6b 15 c6 |2.A..N.<aZ..+k..| 000001a0 a9 cd c2 56 c1 c32a 43 c6 bf fc 0b 46 e8 c7 ee |...V..*C....F...| 000001b0 ea 64 9b 08 42 6a 47 9d 4c ce e7 95 } 

    可以看到部的值都被理了,增加了可性。如果有更多的嵌套,也自增加。二制容也可以有更富的出式比如 Hexdump 。模提供了一 Writer 可以方便地造更多新的式建函。

    例代: https://go.dev/play/p/bPjR5OdA_et

    6 条回复    2022-09-25 03:10:26 +08:00
    kkeep
        1
    kkeep  
       2022-09-18 02:09:25 +08:00 via Android
    有意思
    janxin
        2
    janxin  
       2022-09-18 20:23:07 +08:00
    可以实现 GoStringer 接口吧 https://pkg.go.dev/fmt#GoStringer
    rix
        3
    rix  
    OP
       2022-09-19 01:02:41 +08:00
    @janxin GoStringer 不管理,然可以自己一 helper 理。
    但是如果量大返回 String 很慢而且耗存。Writer 走流可以更好理大量的出。
    Kisesy
        4
    Kisesy  
       2022-09-19 15:59:13 +08:00
    不错,可以自定义打印,我比较常用 github.com/kr/pretty 主要是地址比较好记
    rix
        5
    rix  
    OP
       2022-09-20 03:50:43 +08:00
    @Kisesy 我也是之前一直在用 github.com/kr/pretty 但是需求稍微一就感到不用了
    someonedeng
        6
    someonedeng  
       2022-09-25 03:10:26 +08:00
    好东西,开发的时候比较方便
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     962 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 19:47 PVG 03:47 LAX 12:47 JFK 15:47
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86