1 Star 0 Fork 0

邢楠 / toolbox

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
print.go 4.33 KB
一键复制 编辑 原始数据 按行查看 历史
邢楠 提交于 2020-12-28 08:03 . # 115
/**
* @Author: xing nan
* @Email:457415936@qq.com
* @Time: 2020/12/28 上午8:02
* @File : print
* @Software: GoLand
*/
package com
import (
"fmt"
"reflect"
"strings"
)
const varFormat = "%v"
type value struct {
Arg interface{}
Flag string
}
type pointer struct {
Format string
Ptr uintptr
Addr reflect.Value
}
// Print 打印
func Print(args ...interface{}) {
fmt.Print(Sprintf(format(args...), args...))
}
// Println 打印并换行
func Println(args ...interface{}) {
fmt.Println(Sprintf(format(args...), args...))
}
// Printf 打印并格式化
func Printf(format string, args ...interface{}) {
fmt.Print(Sprintf(format, args...))
}
// Sprint 打印并返回
func Sprint(args ...interface{}) string {
return Sprintf(format(args...), args...)
}
// Sprintln 打印换行并返回
func Sprintln(args ...interface{}) string {
return Sprintf(format(args...)+"\n", args...)
}
// Sprintf 格式化并返回
func Sprintf(format string, args ...interface{}) string {
str := fmt.Sprintf(format, args...) // 放在第一行可以起到效验的作用
pointers := []pointer{}
for _, v := range values(format, args...) {
pointers = append(pointers, extract(reflect.ValueOf(v.Arg), v.Flag)...)
}
// 去重
unique := []pointer{}
for _, p := range pointers {
find := false
for _, u := range unique {
if p.Ptr == u.Ptr {
find = true
}
}
if !find {
unique = append(unique, p)
}
}
return replace(str, unique)
}
// 生成格式
func format(args ...interface{}) string {
formats := []string{}
for i := 0; i < len(args); i++ {
formats = append(formats, varFormat)
}
return strings.Join(formats, " ")
}
// 获取全部指针对象的反射
func values(format string, args ...interface{}) []value {
result := []value{}
for _, v := range filter(format, args...) {
val := reflect.ValueOf(v.Arg)
switch val.Kind() {
case reflect.Struct:
result = append(result, v)
break
case reflect.Ptr:
if !val.Elem().CanAddr() {
continue
}
result = append(result, v)
break
case reflect.Map:
iter := val.MapRange()
for iter.Next() {
result = append(result, value{iter.Value().Interface(), v.Flag})
}
break
case reflect.Slice, reflect.Array:
for i := 0; i < val.Len(); i++ {
result = append(result, value{val.Index(i).Interface(), v.Flag})
}
break
}
}
return result
}
// 过滤无需解析的参数
func filter(format string, args ...interface{}) []value {
fb := []byte(format)
next := len(fb) - 1
loc := -1
result := []value{}
for k, v := range fb {
if v == '%' {
loc += 1
if k+1 <= next {
switch fb[k+1] {
case 'v':
result = append(result, value{
Arg: args[loc],
Flag: "%v",
})
break
case '+':
if k+2 <= next && fb[k+2] == 'v' {
result = append(result, value{
Arg: args[loc],
Flag: "%+v",
})
}
break
case '#':
if k+2 <= next && fb[k+2] == 'v' {
result = append(result, value{
Arg: args[loc],
Flag: "%#v",
})
}
break
}
}
}
}
return result
}
// 提取指针信息
func extract(val reflect.Value, format string) []pointer {
pointers := []pointer{}
switch val.Kind() {
case reflect.Ptr:
elem := val.Elem()
if !elem.CanAddr() {
return pointers
}
pointers = append(pointers, pointer{
Format: format,
Ptr: elem.Addr().Pointer(),
Addr: elem.Addr(),
})
for _, v := range values(format, elem.Interface()) {
pointers = append(pointers, extract(reflect.ValueOf(v.Arg), v.Flag)...)
}
break
case reflect.Struct:
for i := 0; i < val.NumField(); i++ {
if !val.Field(i).CanInterface() {
continue
}
tag := val.Type().Field(i).Tag.Get("xfmt")
if tag == "-" || tag == "_" {
continue
}
for _, v := range values(format, val.Field(i).Interface()) {
pointers = append(pointers, extract(reflect.ValueOf(v.Arg), v.Flag)...)
}
}
break
case reflect.Map, reflect.Slice, reflect.Array:
for _, v := range values(format, val.Interface()) {
pointers = append(pointers, extract(reflect.ValueOf(v.Arg), v.Flag)...)
}
break
}
return pointers
}
// 替换指针为机构体
func replace(str string, pointers []pointer) string {
for _, ptr := range pointers {
ptrString := fmt.Sprintf("0x%x", ptr.Ptr)
str = strings.Replace(str, ptrString, fmt.Sprintf("%s:"+ptr.Format, ptrString, ptr.Addr), 1)
}
return str
}
Go
1
https://gitee.com/xingnan/toolbox.git
git@gitee.com:xingnan/toolbox.git
xingnan
toolbox
toolbox
master

搜索帮助