其他分享
首页 > 其他分享> > go 序列化与反序列化

go 序列化与反序列化

作者:互联网

go 序列化与反序列化

1.1 简介

序列化就是把一个类转换成字符串
反序列化是把一个字符串转换成一个类的实例

2.1 序列化与反序列化实现

2.1.1 对一个字符串类型实现序列化与反序列化

//我们自己实现一个序列化与反序列化
//我们定义一个,传入一个int,序列化成一个string
func Marshal(v int) string {
	return strconv.Itoa(v)
}

func UnMarshal(s string) (int,error){
	return strconv.Atoi(s)
}

func xlhfxlhinit2() {
	var v int= 7
	s := Marshal(v)
	fmt.Println(s)
	r,err := UnMarshal(s)
	if err == nil{
		fmt.Println(r)
	} else {
		fmt.Println(err)
	}
}

2.1.2 对一个接口实现序列化与反序列化,模拟官方的json.Marshal

我们在2.1.1实现对字符串的序列化与反序列化,但是传参是不固定的,下面我们用接口实现接收各种传参

//但是传入的值是不确定的,我们可以把传参改成interface
func Marshal1(v interface{}) ([]byte,error) {  //官方的marshal返回值是byte和error,这里我们也返回byte数组和error
	value := reflect.ValueOf(v)  //我们用反射获取interface传入的类型
	typ := value.Type()  //获取类型并赋值给typ
	switch typ.Kind(){		//switch case 判断typ的类型
		case reflect.Int,reflect.Int8,reflect.Uint:		//判断如果是这几个类型
			//return []byte(strconv.Itoa(int(value.Int()))),nil   //如果只case一个int类型用这个
			return []byte(fmt.Sprintf("%v",value.Interface())),nil
		case reflect.String:
			return []byte(value.String()),nil
		case reflect.Bool:
			return []byte(fmt.Sprintf("%t",value.Bool())),nil
		case reflect.Float32:
			return []byte(fmt.Sprintf("%f",value.Float())),nil
		default:
			//return "",errors.New("暂时不支持这种类型") //自定义返回报错类型
			return []byte(""),fmt.Errorf("暂时不支持这种类型")  //这种自定义报错类型也可以
			}
}
func UnMarshal1(v interface{},data []byte) error{ //官方的UnMarshal是传入一个参数和data,返回error
	value := reflect.ValueOf(v)
	typ := value.Type()
	//typ := reflect.TypeOf(v)  //和上面的一行同样都可以获取
	if typ.Kind() != reflect.Ptr { //因为我们想在这里面直接修改外面的值,所以这里必须是指针类型
		return errors.New("必须是指针,否则无法修改v的值")
	} else {
		typ = typ.Elem() // 如果不是指针就转换成指针
		value = value.Elem()
	}
	s := string(data) //直接调string,把byte类型的data转换成string
	switch typ.Kind(){ //判断类型,我们把data的值传给v,以达到修改值的目的
		case reflect.Int:
			if i,err := strconv.ParseInt(s,10,64);err == nil {//strconv.ParseInt把string转换成int,10是十进制,64是64位的意思
				value.SetInt(i) //把value的值改成 i,i是由s的值来的,s是data的值来的,也就是把data的值给了v
			} else {
				return err
			}
		case reflect.Uint:
			if i,err := strconv.ParseUint(s,10,64);err == nil {//strconv.ParseInt把string转换成uint,10是十进制,64是64位的意思
				value.SetUint(i) //把value的值改成 i,i是由s的值来的,s是data的值来的,也就是把data的值给了v
			} else {
				return err
			}
		case reflect.Bool:
			if i,err := strconv.ParseBool(s);err == nil {
				value.SetBool(i)
			} else {
				return err
			}
		case reflect.Float32,reflect.Float64:
			if i,err := strconv.ParseFloat(s,64);err == nil {
				value.SetFloat(i)
			} else {
				return err
			}
		case reflect.String:
			value.SetString(s)
		default:
			return errors.New("暂时不支持这种类型")
	}
	return nil
}

func main() {
	var v interface{}
	v = 7
	if data,err := Marshal1(v);err == nil {
		fmt.Println(string(data)) //这里用Marshall把v=7,int类型转换成byte类型, 然后打印的时候再转换成string类型

		var a int = 5	//定义一个a=5
		UnMarshal1(&a,data) //用UnMarshal1修改a的值为7
		fmt.Println(a) //打印出7
	}

}

标签:return,err,value,reflect,go,byte,序列化
来源: https://www.cnblogs.com/liwenchao1995/p/16169846.html