Go json裁剪

2020-10-30 23:55:31

背景

项目中遇到一个使用场景:服务端要保存用户上传的json格式示例,但是服务端针对这个json格式示例有大小限制,比如1KB,超过这个大小后服务端就不能正常保存了。此时用户正好手里有个比较大(>1KB)的json示例,他要想将这个示例正常保存可以进行两种不同操作:

  1. 手动去裁剪这个json字符串;
  2. 通过智能的方式自动将一些重复且不必要的数据删除掉,以达到json裁剪的目的

显然,针对第一种方式不太明智,那我们如果采用第二种方式的话,又该怎么做呢?

操刀

在Go里面,我们引用官方标准库encoding/json对json进行序列化和反序列化时用的最多的也是下面的两个方法:

  • func Unmarshal(data []byte, v interface{}) error
  • func Marshal(v interface{}) ([]byte, error)

注意里面的入参interface类型参数,第一个是将data里面数据反序列化到v中,第二个是将v中参数序列化成json字符串。而我们json格式对象常用的格式基本上都是下面这两种类型的:

[
    xxx,xxx,...
]

{
    xxx:ooo,...
}

我们正好可以分别用[]interface{}表示数组和map[string]interface{}表示大对象,然后顺理成章的采用递归的方式,循环处理里面的数据。
代码如下:

func knife(itf interface{}) interface{} {
	var t interface{}

	if _, ok := itf.(string); ok {
		t = ""
	} else if im, ok := itf.(map[string]interface{}); ok {
		for k := range im {
			im[k] = knife(im[k])
		}
		t = im
	} else if ia, ok := itf.([]interface{}); ok {
		if len(ia) != 0 {
			t = []interface{}{knife(ia[0])}
		} else {
			t = ia
		}
	} else {
		t = itf
	}

	return t
}

上面knife方法实现的机制为:

  1. 采用递归循环判断传递进来的对象类型,如果为map对象则对map中每个key所对应的value值进行循环判断,如果为数组对象则直接选取数组对象中的第一个元素;
  2. 上面例子中奖所有string类型value全都重置成了空字符串

然后达到了裁剪json的目的,且不损失json格式完整性。

注:

  • 以上方式主要目的是给你们一个启迪作用,具体要达到怎样的效果,可以根据实际也许需求来执行,比如要在一个未知的json里面新增固定key:value、字符串批量替换等骚操作都可以采用这种方式稍微魔改一下就行了。
golang 判断interface是否为空nil

前言 interface很好用,可以存取任意类型,但我们在使用这个值类型的时候我们往往又需要知道该interface是属于哪种类型的,以便正确使用这个值。比如,如果我们提前知道该interface为int,则都是这样使用: var a interface{} a = 5 fmt.Println(2*a.(int)) 而往往我们interface可能会存放多种不同类型的数据,为了健壮,在使用时我们需要判断interface里面存放的到底为何种类型的数据,以及这些数据是否为空?比如你引用了一个类型里面的空对象是很容易引发panic的。 我们通过什么方式判断interface是否为空呢? 先明确一点:一个interface里面存在动态类型和动态值,只有当动态类型和动态值都为空时,该interface才为空(nil) 比如: package main import "fmt" func main(){ var a interface{} = nil var b interface{} = (*int)(nil) fmt.Println(a=

sh、bash和zsh区别

简介 Shell是一种脚本语言,是用户使用Linux的桥梁,要让这些脚本语言run起来,就必须要有解释器来执行这些脚本。而sh、bash、zsh就是脚本解释器,习惯上把它们陈祚一种shell,我们常说有多少种shell,其实说的就是shell脚本解释器。 sh Bourne Shell,是一个早期的重要shell,1978年由史蒂夫·伯恩编写,并同Version 7 Unix一起发布。 bash Bourne-Again Shell,是一个为GNU计划编写的Unix shell。1987年由布莱恩·福克斯创造。主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。 zsh 也称为Z shell,是Bourne Shell(sh)的扩展版本,具有大量新功能,并支持插件和主题。 由于它基于与Bash相同的shell,因此ZSH具有许多相同的功能,并且切换是轻而易举的。 区别 1.sh是bash的一种特殊模式,