지금 고로 짠건 이렇게 짯거든요

코드 남보여 주는건 첨이라 너무 부끄러운데. 쨌든


구조체를 넘겨주면 필드 순회 하면서 바이트 배열로 바꿔주는 코드

func Decode(t interface{}) []byte {     var BINARY []byte     var Val = reflect.ValueOf(t)     var Typ = reflect.TypeOf(t)     var Knd = Val.Kind()     _ = Typ     if Knd == reflect.Ptr {         if Val.IsNil() {             return nil         }         Val = Val.Elem()         Typ = Val.Type()         Knd = Val.Kind()     }     // Handle value depend on itself's type     switch Knd {     // If type is Struct, we first trying to copy that     // Because, without this process, if it is un-exported field, it will Panic.     // After that, we will iterate whole fields.     case reflect.Struct:         var numField = Val.NumField()         // copy //         copiedOne := reflect.New(Val.Type()).Elem()         copiedOne.Set(Val)         //////////         for i := 0; i < numField; i++ {             // field //             var valField = copiedOne.Field(i)             valField = reflect.NewAt(valField.Type(), unsafe.Pointer(valField.UnsafeAddr())).Elem()             /////////             BINARY = append(BINARY, Decode(valField.Interface())...)         }         // NOTE: We simply tlqkfduddjwhwrkxsp         // If you can sure that safe to use, you can modify to act like `(SIZE OF ELEMENT) * (BINARY OF ARRAY/SLICE)`     case reflect.Array:         for i := 0; i < Val.Len(); i++ {             BINARY = append(BINARY, Decode(Val.Index(i).Interface())...)         }         // If type is Primitive type, especially Number-like type,         // it will it self's size     case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:         BINARY = append(BINARY, uintToSlice(Val.Interface())...)     }     return BINARY }



요건 빈 구조체에 바이너리 다시 덮어 씌우는거

func Encode(obj interface{}, bin []byte) error {     size := Size(reflect.ValueOf(obj).Interface())     if size != len(bin) {         log.Panic()         return errors.New("Size of structure and size of given []byte is different")     }     index := 0     e := reflect.ValueOf(obj).Elem()     fieldNum := e.NumField()     for i := 0; i < fieldNum; i++ {         v := e.Field(i)         // Note: showing size of structure which measured by v.Type.Size() will NOT correct, due to byte alignment.         // It works properly, in our situation, but if you really want to know actual size of that, use Size() at below.         // fmt.Printf("Processing field %d/%d, Datatype: %s, ytes\n", i+1, fieldNum, v.Kind().String(), v.Type().Size())         switch v.Kind() {         case reflect.Uint8:             e.Field(i).SetUint(uint64(bin[index]))             index++         case reflect.Uint16:             e.Field(i).SetUint(uint64(binary.BigEndian.Uint16(bin[index : index+2])))             index += 2         case reflect.Uint32:             e.Field(i).SetUint(uint64(binary.BigEndian.Uint32(bin[index : index+4])))             index += 4         case reflect.Uint64:             e.Field(i).SetUint(uint64(binary.BigEndian.Uint64(bin[index : index+8])))             index += 8         case reflect.Array:             reflect.Copy(e.Field(i), reflect.ValueOf(bin[index:index+e.Field(i).Len()]))             index += e.Field(i).Len()         case reflect.Struct:             len := Size(v.Interface())             Encode(v.Addr().Interface(), bin[index:index+len])             index += len         }     }     return nil }



포인터 역참조 하는 코드도 어디 있었는데 못찾겠네용...


혹시 러스트는 이런게 쉽게? 세이프하게? 되나 해서 물어봤슴니다.