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