tostr

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2023 License: MIT Imports: 12 Imported by: 2

README

tostr包用于生成指定golang对象对应的字符串, 该字符串以易于阅读的方式呈现指定对象的内容.
tostr包中相关函数的实现基于一种明确定义的有向图, 该有向图中的结点和边如下:
对象obj为有向图的源点, 任意结点的后继结点如下:

 (1) 如果v.Kind()为reflect.Slice, 则切片v中包含的所有元素为v的后继结点   
 (2) 如果v.Kind()为reflect.Interface, 则v.Elem()为v的后继结点    
 (3) 如果v.Kind()为reflect.Array, 则v中包含的所有元素为v的后继结点   
 (4) 如果v.Kind()为reflect.Struct, 则v的所有字段对应的值为v的后继结点    
 (5) 如果v.Kind()为reflect.Map, 则v中所有Key, Value为v的后继结点

对于任意结点v, 当且仅当v满足如下条件时, v不存在后继结点:

 (1) v.Kind()与后面给出的某个值相等: reflect.Invalid, reflect.String, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Chan, reflect.Func, reflect.UnsafePointer    
 (2) v.Kind()为reflect.Interface且v.IsNil()为true    
 (3) v.Kind()为reflect.Array且v.Len()为0    
 (4) v.Kind()为reflect.Slice且v.IsNil()为true或v.Len()为0    
 (5) v.Kind()为reflect.Struct且cur.NumField()为0    
 (6) v.Kind()的值为reflect.Map且v.IsNil()为true或v.Len()为0    
 (7) v.Kind()的值为reflect.Ptr且v.IsNil()为true

所有指向指针的指针类型结点均视为两两不同的结点
将[]T类型的切片中直接包含的元素视为*T, 也即指向T类型的指针, 该指针指向的对象即为切片真实包含的元素.
如果两个对象满足如下条件之一, 则这两个对象在有向图中对应同一个结点:
 (1) 为同类型的指针, 值不为nil且存储的地址值相等
 (2) 为同类型的map, 值不为nil, map不为空且两个对象(map类型的变量实际对应一个指针值)的值相等
为使生成字符串的长度尽量少, 同时保证的生成字符串的直观性, 在遍历过程中遇到的重复的指针类型和map类型的结点时第1次遍历时完整
的呈现对象, 同时给对象编号, 编号形如Obj1, Obj2..., 之后再遇到该对象时使用占位符替换, 占位符形如$Obj1, $Obj2...,
 使用tostr.String不会展示对象的类型信息, 如果需要展示对象的类型信息也可以使用tostr.StringByConf, 通过传入的conf进行控制
例如: 下面的程序:

package main

import (
	 "fmt"
	 "github.com/gogokit/tostr"
)

func main() {
	 type Struct struct {
		 str string
	 }
	 s := Struct{
		 str: "str",
	 }
	 arr2 := []*Struct{&s, &s}
	 num := 1
	 arr1 := []*int{&num, &num}
	 fmt.Printf("arr2:%v\n", tostr.String(arr2))
	 fmt.Printf("arr1:%v\n", tostr.String(arr1))
	 arr2Str := tostr.StringByConf(arr2, tostr.Config{
		 InformationLevel: tostr.AllTypesInfo,
	 })
	 fmt.Printf("arr2Str:%v\n", arr2Str)
	 arr1Str := tostr.StringByConf(arr1, tostr.Config{
		 InformationLevel: tostr.AllTypesInfo,
	 })
	 fmt.Printf("arr1Str:%v\n", arr1Str)
}

输出内容如下:

arr2:[<Obj1>{str:"str"}, $Obj1]    
arr1:[1, 1]     
arr2Str:([]*main.Struct)[(*<Obj1>main.Struct){str:(string)"str"}, $Obj1]    
arr1Str:([]*int)[(*int)1, (*int)1]

为了进一步降低生成字符串的长度, 对于同类型的多个切片, 如果这些切片引用的底层数组之间存在共用的部分将对切片中的元素进行聚合, 保证该类型切片中 统一地址上的对象仅被打印一遍, 例如: 对于下面的程序:

package main

import (
	"fmt"

	"github.com/gogokit/tostr"
)

func main() {
	type Struct struct {
		slice1 []int
		slice2 []int
	}
	slice := []int{1, 2, 3, 4, 5}
	s := Struct{
		slice1: slice,
		slice2: slice[1:3],
	}
	fmt.Printf("%v\n", tostr.String(s))
	fs, _ := tostr.Fmt(tostr.String(s), 2)
	fmt.Printf("\n%v\n", fs)
}

输出内容如下:

{slice1:$Obj1(0-4), slice2:$Obj1(1-2)}, {<Obj1>:[1(0), 2(1), 3(2), 4, 5(4)]}

{
  slice1:$Obj1(0-4),
  slice2:$Obj1(1-2)
},
{
  <Obj1>:[
    1(0),
    2(1),
    3(2),
    4,
    5(4)
  ]
}

上面的输出中slice1对应$Obj1(0-4)表示slice1中元素依次为Obj1的下标0至4之间的元素, slice2对应$Obj1(1-2)表示slice2中的元素依
次为Obj1的下标1至2之间的元素, 切片Obj1中的每个元素后面括号中的数字表示元素在Obj1中的下标

最后, 如果生成的字符串过大导致不便于阅读时可以使用本包下的Fmt函数格式化一下, 格式化之后层次分明, 阅读方便.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterByFieldName added in v1.0.3

func FilterByFieldName(names ...string) func(obj reflect.Value, fieldIdx int) (hitFilter bool)

func Fmt

func Fmt(s string, indentSpacesCount uint8) (string, error)

返回tostr.String生成的字符串格式化之后的结果, indentSpacesCount指定缩进使用的空格数. 例如: s为:"{slice:[1, 2, 3], m:{1:"string", 2:"var"}}", indentSpacesCount为4, 则格式化后的结果如下:

{
    slice:[
        1,
        2,
        3
    ],
    m:{
        1:"string",
        2:"var"
    }
}

func NotExportFieldFilter added in v1.0.3

func NotExportFieldFilter(obj reflect.Value, fieldIdx int) (hitFilter bool)

func ProtobufFieldFilter added in v1.0.3

func ProtobufFieldFilter(obj reflect.Value, fieldIdx int) (hitFilter bool)

func String

func String(obj interface{}) string

func StringByConf

func StringByConf(obj interface{}, conf Config) (ret string)

func Stringer

func Stringer(obj interface{}, filterStructField ...string) fmt.Stringer

func StringerByConf

func StringerByConf(obj interface{}, conf Config) fmt.Stringer

func StringerKvs added in v1.0.3

func StringerKvs(kvs ...interface{}) fmt.Stringer

Types

type Config

type Config struct {
	InformationLevel InformationLevel
	// 返回true表示过滤掉field对应的结点, 也即不在对field对应的结点递归访问
	FilterStructField []func(obj reflect.Value, fieldIdx int) (hitFilter bool)
	// FastSpecifyToStringProbe(obj)返回true时,使用ToString(obj)作为obj的字符串呈现结果
	ToString func(obj reflect.Value) (objStr string)
	// FastSpecifyToStringProbe(obj)需高效返回obj是否存在指定的String函数,存在时返回true
	FastSpecifyToStringProbe func(obj reflect.Value) (hasSpecifyToString bool)
	// 生成字符串的过程中,如果中途字符串的字节数超过WarnSize,则会调用ResultTooLongCallback(str),str表示当前已经生成的字符串,返回true表示继续执行,返回false表示终止执行
	ResultSizeWarnCallback func(str string) (shouldContinue bool)
	// 仅在非nil时表示指定警戒字节数
	WarnSize          *int
	DisableMapKeySort bool
}

func GetDefaultConfig added in v1.0.3

func GetDefaultConfig() Config

返回全局默认配置的深拷贝

func (Config) AppendFilter added in v1.0.3

func (c Config) AppendFilter(fs ...func(obj reflect.Value, fieldIdx int) (hitFilter bool)) Config

func (Config) Clone added in v1.0.3

func (c Config) Clone() Config

func (Config) SetFilters added in v1.0.3

func (c Config) SetFilters(fs ...func(obj reflect.Value, fieldIdx int) (hitFilter bool)) Config

func (Config) SetInformationLevel added in v1.0.3

func (c Config) SetInformationLevel(l InformationLevel) Config

func (Config) SetWarnSize added in v1.0.3

func (c Config) SetWarnSize(s int) Config

func (Config) Stringer added in v1.0.3

func (c Config) Stringer(obj interface{}) fmt.Stringer

func (Config) StringerKvs added in v1.0.3

func (c Config) StringerKvs(kvs ...interface{}) fmt.Stringer

type InformationLevel

type InformationLevel int32
const (
	// 不展示类型信息
	NoTypesInfo InformationLevel = iota
	// 展示除基本类型之外的类型信息
	NoBaseKindsInfoOnly
	// 展示所有的类型信息
	AllTypesInfo
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL