This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new e44566587 refactor(go): rename go interface{} to any (#3128)
e44566587 is described below
commit e4456658764fbde5876b45dace3cbbd9522730a6
Author: Shawn Yang <[email protected]>
AuthorDate: Mon Jan 12 16:30:14 2026 +0800
refactor(go): rename go interface{} to any (#3128)
<!--
**Thanks for contributing to Apache Fory™.**
**If this is your first time opening a PR on fory, you can refer to
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).**
Contribution Checklist
- The **Apache Fory™** community has requirements on the naming of pr
titles. You can also find instructions in
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).
- Apache Fory™ has a strong focus on performance. If the PR you submit
will have an impact on performance, please benchmark it first and
provide the benchmark result here.
-->
## Why?
<!-- Describe the purpose of this PR. -->
## What does this PR do?
<!-- Describe the details of this PR. -->
## Related issues
#2982
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fory/issues/new/choose) describing the
need to do so and update the document if necessary.
Delete section if not applicable.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
Delete section if not applicable.
-->
---
docs/guide/xlang/serialization.md | 18 +++---
docs/guide/xlang/zero-copy.md | 4 +-
go/README.md | 2 +-
go/fory/array_test.go | 20 +++----
go/fory/codegen/decoder.go | 44 ++++++++------
go/fory/codegen/encoder.go | 47 ++++++++-------
go/fory/codegen/guard.go | 14 ++++-
go/fory/codegen/utils.go | 16 ++++-
go/fory/errors.go | 6 +-
go/fory/field_info.go | 2 +-
go/fory/fory.go | 32 +++++-----
go/fory/fory_compatible_test.go | 40 ++++++-------
go/fory/fory_test.go | 72 +++++++++++------------
go/fory/map.go | 4 +-
go/fory/reader.go | 6 +-
go/fory/ref_resolver_test.go | 10 ++--
go/fory/skip.go | 6 +-
go/fory/slice_dyn.go | 4 +-
go/fory/struct.go | 12 ++--
go/fory/struct_test.go | 39 +++++--------
go/fory/tests/generator_test.go | 6 +-
go/fory/tests/generator_xlang_test.go | 6 +-
go/fory/tests/structs.go | 2 +-
go/fory/tests/structs_fory_gen.go | 32 +++++-----
go/fory/tests/xlang/xlang_test_main.go | 104 ++++++++++++++++-----------------
go/fory/threadsafe/fory.go | 8 +--
go/fory/type_def.go | 6 +-
go/fory/type_def_test.go | 2 +-
go/fory/type_resolver.go | 19 +++---
go/fory/type_test.go | 2 +-
30 files changed, 304 insertions(+), 281 deletions(-)
diff --git a/docs/guide/xlang/serialization.md
b/docs/guide/xlang/serialization.md
index fa8d1cc3b..a8d1c1b96 100644
--- a/docs/guide/xlang/serialization.md
+++ b/docs/guide/xlang/serialization.md
@@ -79,19 +79,19 @@ import forygo "github.com/apache/fory/go/fory"
import "fmt"
func main() {
- list := []interface{}{true, false, "str", -1.1, 1, make([]int32, 10),
make([]float64, 20)}
+ list := []any{true, false, "str", -1.1, 1, make([]int32, 10),
make([]float64, 20)}
fory := forygo.NewFory()
bytes, err := fory.Marshal(list)
if err != nil {
panic(err)
}
- var newValue interface{}
+ var newValue any
// bytes can be deserialized by other languages
if err := fory.Unmarshal(bytes, &newValue); err != nil {
panic(err)
}
fmt.Println(newValue)
- dict := map[string]interface{}{
+ dict := map[string]any{
"k1": "v1",
"k2": list,
"k3": -1,
@@ -271,9 +271,9 @@ import "fmt"
func main() {
type SomeClass1 struct {
- F1 interface{}
+ F1 any
F2 string
- F3 []interface{}
+ F3 []any
F4 map[int8]int32
F5 int8
F6 int16
@@ -286,7 +286,7 @@ func main() {
}
type SomeClass2 struct {
- F1 interface{}
+ F1 any
F2 map[int8]int32
}
fory := forygo.NewFory()
@@ -302,7 +302,7 @@ func main() {
obj := &SomeClass1{}
obj.F1 = obj1
obj.F2 = "abc"
- obj.F3 = []interface{}{"abc", "abc"}
+ obj.F3 = []any{"abc", "abc"}
f4 := map[int8]int32{1: 2}
obj.F4 = f4
obj.F5 = fory.MaxInt8
@@ -317,7 +317,7 @@ func main() {
if err != nil {
panic(err)
}
- var newValue interface{}
+ var newValue any
// bytes can be deserialized by other languages
if err := fory.Unmarshal(bytes, &newValue); err != nil {
panic(err)
@@ -493,7 +493,7 @@ func main() {
if err != nil {
panic(err)
}
- var newValue interface{}
+ var newValue any
// bytes can be deserialized by other languages
if err := fory.Unmarshal(bytes, &newValue); err != nil {
panic(err)
diff --git a/docs/guide/xlang/zero-copy.md b/docs/guide/xlang/zero-copy.md
index 18e5b736a..de73a3d06 100644
--- a/docs/guide/xlang/zero-copy.md
+++ b/docs/guide/xlang/zero-copy.md
@@ -118,7 +118,7 @@ func main() {
fory := forygo.NewFory()
// Data with large arrays
- list := []interface{}{
+ list := []any{
"str",
make([]byte, 1000), // Large byte array
}
@@ -139,7 +139,7 @@ func main() {
}
// Deserialize with buffers
- var newList []interface{}
+ var newList []any
if err := fory.Deserialize(buf, &newList, buffers); err != nil {
panic(err)
}
diff --git a/go/README.md b/go/README.md
index 0f5985e08..6715605eb 100644
--- a/go/README.md
+++ b/go/README.md
@@ -65,7 +65,7 @@ func main() {
- `[]bool`, `[]int16`, `[]int32`, `[]int64`
- `[]float32`, `[]float64`
- `[]string`
-- `[]interface{}` (dynamic slice)
+- `[]any` (dynamic slice)
- `map[string]string`, `map[int]int`, `map[string]int`, and more
### Time Types
diff --git a/go/fory/array_test.go b/go/fory/array_test.go
index 1fed41d93..2fe0a7461 100644
--- a/go/fory/array_test.go
+++ b/go/fory/array_test.go
@@ -32,7 +32,7 @@ func TestArrayDynSerializer(t *testing.T) {
})
t.Run("accepts interface element type", func(t *testing.T) {
- var arr [3]interface{}
+ var arr [3]any
_, err := newArrayDynSerializer(reflect.TypeOf(arr).Elem())
require.NoError(t, err)
})
@@ -42,17 +42,17 @@ func TestArrayDynSerializerRoundTrip(t *testing.T) {
f := NewFory()
t.Run("array of interfaces with strings", func(t *testing.T) {
- arr := [3]interface{}{"hello", "world", "test"}
+ arr := [3]any{"hello", "world", "test"}
bytes, err := f.Marshal(arr)
require.NoError(t, err)
- var result interface{}
+ var result any
err = f.Unmarshal(bytes, &result)
require.NoError(t, err)
// Result will be a slice, not an array
- resultSlice, ok := result.([]interface{})
+ resultSlice, ok := result.([]any)
require.True(t, ok)
require.Equal(t, 3, len(resultSlice))
require.Equal(t, arr[0], resultSlice[0])
@@ -61,16 +61,16 @@ func TestArrayDynSerializerRoundTrip(t *testing.T) {
})
t.Run("array of interfaces with nil", func(t *testing.T) {
- arr := [3]interface{}{"hello", nil, "world"}
+ arr := [3]any{"hello", nil, "world"}
bytes, err := f.Marshal(arr)
require.NoError(t, err)
- var result interface{}
+ var result any
err = f.Unmarshal(bytes, &result)
require.NoError(t, err)
- resultSlice, ok := result.([]interface{})
+ resultSlice, ok := result.([]any)
require.True(t, ok)
require.Equal(t, 3, len(resultSlice))
require.Equal(t, arr[0], resultSlice[0])
@@ -79,16 +79,16 @@ func TestArrayDynSerializerRoundTrip(t *testing.T) {
})
t.Run("array of interfaces with mixed types", func(t *testing.T) {
- arr := [4]interface{}{"string", int32(42), true, float64(3.14)}
+ arr := [4]any{"string", int32(42), true, float64(3.14)}
bytes, err := f.Marshal(arr)
require.NoError(t, err)
- var result interface{}
+ var result any
err = f.Unmarshal(bytes, &result)
require.NoError(t, err)
- resultSlice, ok := result.([]interface{})
+ resultSlice, ok := result.([]any)
require.True(t, ok)
require.Equal(t, 4, len(resultSlice))
require.Equal(t, arr[0], resultSlice[0])
diff --git a/go/fory/codegen/decoder.go b/go/fory/codegen/decoder.go
index 77853c7d5..6e6255033 100644
--- a/go/fory/codegen/decoder.go
+++ b/go/fory/codegen/decoder.go
@@ -152,25 +152,27 @@ func generateFieldReadTyped(buf *bytes.Buffer, field
*FieldInfo) error {
// Handle slice types
if slice, ok := field.Type.(*types.Slice); ok {
elemType := slice.Elem()
- // Check if element type is interface{} (dynamic type)
- if iface, ok := elemType.(*types.Interface); ok &&
iface.Empty() {
- // For []interface{}, we need to manually implement the
deserialization
+ // Check if element type is any (dynamic type)
+ // Unwrap alias types (e.g., 'any' is an alias for
'interface{}')
+ unwrappedElem := types.Unalias(elemType)
+ if iface, ok := unwrappedElem.(*types.Interface); ok &&
iface.Empty() {
+ // For []any, we need to manually implement the
deserialization
// to match our custom encoding.
// In xlang mode, slices are NOT nullable by default.
// In native Go mode, slices can be nil and need null
flags.
- fmt.Fprintf(buf, "\t// Dynamic slice []interface{}
handling - manual deserialization\n")
+ fmt.Fprintf(buf, "\t// Dynamic slice []any handling -
manual deserialization\n")
fmt.Fprintf(buf, "\t{\n")
fmt.Fprintf(buf, "\t\tisXlang :=
ctx.TypeResolver().IsXlang()\n")
fmt.Fprintf(buf, "\t\tif isXlang {\n")
fmt.Fprintf(buf, "\t\t\t// xlang mode: slices are not
nullable, read directly without null flag\n")
fmt.Fprintf(buf, "\t\t\tsliceLen :=
int(buf.ReadVaruint32(err))\n")
fmt.Fprintf(buf, "\t\t\tif sliceLen == 0 {\n")
- fmt.Fprintf(buf, "\t\t\t\t%s = make([]interface{},
0)\n", fieldAccess)
+ fmt.Fprintf(buf, "\t\t\t\t%s = make([]any, 0)\n",
fieldAccess)
fmt.Fprintf(buf, "\t\t\t} else {\n")
fmt.Fprintf(buf, "\t\t\t\t// ReadData collection flags
(ignore for now)\n")
fmt.Fprintf(buf, "\t\t\t\t_ = buf.ReadInt8(err)\n")
fmt.Fprintf(buf, "\t\t\t\t// Create slice with proper
capacity\n")
- fmt.Fprintf(buf, "\t\t\t\t%s = make([]interface{},
sliceLen)\n", fieldAccess)
+ fmt.Fprintf(buf, "\t\t\t\t%s = make([]any,
sliceLen)\n", fieldAccess)
fmt.Fprintf(buf, "\t\t\t\t// ReadData each element
using ReadValue\n")
fmt.Fprintf(buf, "\t\t\t\tfor i := range %s {\n",
fieldAccess)
fmt.Fprintf(buf,
"\t\t\t\t\tctx.ReadValue(reflect.ValueOf(&%s[i]).Elem(), fory.RefModeTracking,
true)\n", fieldAccess)
@@ -184,12 +186,12 @@ func generateFieldReadTyped(buf *bytes.Buffer, field
*FieldInfo) error {
fmt.Fprintf(buf, "\t\t\t} else {\n")
fmt.Fprintf(buf, "\t\t\t\tsliceLen :=
int(buf.ReadVaruint32(err))\n")
fmt.Fprintf(buf, "\t\t\t\tif sliceLen == 0 {\n")
- fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]interface{},
0)\n", fieldAccess)
+ fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]any, 0)\n",
fieldAccess)
fmt.Fprintf(buf, "\t\t\t\t} else {\n")
fmt.Fprintf(buf, "\t\t\t\t\t// ReadData collection
flags (ignore for now)\n")
fmt.Fprintf(buf, "\t\t\t\t\t_ = buf.ReadInt8(err)\n")
fmt.Fprintf(buf, "\t\t\t\t\t// Create slice with proper
capacity\n")
- fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]interface{},
sliceLen)\n", fieldAccess)
+ fmt.Fprintf(buf, "\t\t\t\t\t%s = make([]any,
sliceLen)\n", fieldAccess)
fmt.Fprintf(buf, "\t\t\t\t\t// ReadData each element
using ReadValue\n")
fmt.Fprintf(buf, "\t\t\t\t\tfor i := range %s {\n",
fieldAccess)
fmt.Fprintf(buf,
"\t\t\t\t\t\tctx.ReadValue(reflect.ValueOf(&%s[i]).Elem(),
fory.RefModeTracking, true)\n", fieldAccess)
@@ -216,10 +218,11 @@ func generateFieldReadTyped(buf *bytes.Buffer, field
*FieldInfo) error {
return nil
}
- // Handle interface types
- if iface, ok := field.Type.(*types.Interface); ok {
+ // Handle interface types (including 'any' which is an alias for
interface{})
+ unwrappedType := types.Unalias(field.Type)
+ if iface, ok := unwrappedType.(*types.Interface); ok {
if iface.Empty() {
- // For interface{}, use ReadValue for dynamic type
handling
+ // For any, use ReadValue for dynamic type handling
fmt.Fprintf(buf,
"\tctx.ReadValue(reflect.ValueOf(&%s).Elem(), fory.RefModeTracking, true)\n",
fieldAccess)
return nil
}
@@ -607,10 +610,11 @@ func generateSliceElementReadInline(buf *bytes.Buffer,
elemType types.Type, elem
return nil
}
- // Handle interface types
- if iface, ok := elemType.(*types.Interface); ok {
+ // Handle interface types (including 'any' which is an alias for
interface{})
+ unwrappedElem := types.Unalias(elemType)
+ if iface, ok := unwrappedElem.(*types.Interface); ok {
if iface.Empty() {
- // For interface{} elements, use ReadValue for dynamic
type handling
+ // For any elements, use ReadValue for dynamic type
handling
fmt.Fprintf(buf,
"\t\t\t\tctx.ReadValue(reflect.ValueOf(&%s).Elem(), fory.RefModeTracking,
true)\n", elemAccess)
return nil
}
@@ -704,13 +708,15 @@ func generateMapReadInline(buf *bytes.Buffer, mapType
*types.Map, fieldAccess st
keyType := mapType.Key()
valueType := mapType.Elem()
- // Check if key or value types are interface{}
+ // Check if key or value types are any (unwrap aliases like 'any')
keyIsInterface := false
valueIsInterface := false
- if iface, ok := keyType.(*types.Interface); ok && iface.Empty() {
+ unwrappedKey := types.Unalias(keyType)
+ unwrappedValue := types.Unalias(valueType)
+ if iface, ok := unwrappedKey.(*types.Interface); ok && iface.Empty() {
keyIsInterface = true
}
- if iface, ok := valueType.(*types.Interface); ok && iface.Empty() {
+ if iface, ok := unwrappedValue.(*types.Interface); ok && iface.Empty() {
valueIsInterface = true
}
@@ -780,7 +786,7 @@ func writeMapReadChunks(buf *bytes.Buffer, mapType
*types.Map, fieldAccess strin
// ReadData key
if keyIsInterface {
- fmt.Fprintf(buf, "%s\t\tvar mapKey interface{}\n", indent)
+ fmt.Fprintf(buf, "%s\t\tvar mapKey any\n", indent)
fmt.Fprintf(buf,
"%s\t\tctx.ReadValue(reflect.ValueOf(&mapKey).Elem(), fory.RefModeTracking,
true)\n", indent)
} else {
keyVarType := getGoTypeString(keyType)
@@ -792,7 +798,7 @@ func writeMapReadChunks(buf *bytes.Buffer, mapType
*types.Map, fieldAccess strin
// ReadData value
if valueIsInterface {
- fmt.Fprintf(buf, "%s\t\tvar mapValue interface{}\n", indent)
+ fmt.Fprintf(buf, "%s\t\tvar mapValue any\n", indent)
fmt.Fprintf(buf,
"%s\t\tctx.ReadValue(reflect.ValueOf(&mapValue).Elem(), fory.RefModeTracking,
true)\n", indent)
} else {
valueVarType := getGoTypeString(valueType)
diff --git a/go/fory/codegen/encoder.go b/go/fory/codegen/encoder.go
index 49c3db3f2..d3552681f 100644
--- a/go/fory/codegen/encoder.go
+++ b/go/fory/codegen/encoder.go
@@ -139,13 +139,15 @@ func generateFieldWriteTyped(buf *bytes.Buffer, field
*FieldInfo) error {
// Handle slice types
if slice, ok := field.Type.(*types.Slice); ok {
elemType := slice.Elem()
- // Check if element type is interface{} (dynamic type)
- if iface, ok := elemType.(*types.Interface); ok &&
iface.Empty() {
- // For []interface{}, we need to manually implement the
serialization
+ // Check if element type is any (dynamic type)
+ // Unwrap alias types (e.g., 'any' is an alias for
'interface{}')
+ unwrappedElem := types.Unalias(elemType)
+ if iface, ok := unwrappedElem.(*types.Interface); ok &&
iface.Empty() {
+ // For []any, we need to manually implement the
serialization
// because WriteValue produces incorrect length
encoding.
// In xlang mode, slices are NOT nullable by default.
// In native Go mode, slices can be nil and need null
flags.
- fmt.Fprintf(buf, "\t// Dynamic slice []interface{}
handling - manual serialization\n")
+ fmt.Fprintf(buf, "\t// Dynamic slice []any handling -
manual serialization\n")
fmt.Fprintf(buf, "\t{\n")
fmt.Fprintf(buf, "\t\tisXlang :=
ctx.TypeResolver().IsXlang()\n")
fmt.Fprintf(buf, "\t\tif isXlang {\n")
@@ -156,7 +158,7 @@ func generateFieldWriteTyped(buf *bytes.Buffer, field
*FieldInfo) error {
fmt.Fprintf(buf, "\t\t\t}\n")
fmt.Fprintf(buf,
"\t\t\tbuf.WriteVaruint32(uint32(sliceLen))\n")
fmt.Fprintf(buf, "\t\t\tif sliceLen > 0 {\n")
- fmt.Fprintf(buf, "\t\t\t\t// WriteData collection flags
for dynamic slice []interface{}\n")
+ fmt.Fprintf(buf, "\t\t\t\t// WriteData collection flags
for dynamic slice []any\n")
fmt.Fprintf(buf, "\t\t\t\t// Only CollectionTrackingRef
is set (no declared type, may have different types)\n")
fmt.Fprintf(buf, "\t\t\t\tbuf.WriteInt8(1) //
CollectionTrackingRef only\n")
fmt.Fprintf(buf, "\t\t\t\t// WriteData each element
using WriteValue\n")
@@ -173,7 +175,7 @@ func generateFieldWriteTyped(buf *bytes.Buffer, field
*FieldInfo) error {
fmt.Fprintf(buf, "\t\t\t\tsliceLen := len(%s)\n",
fieldAccess)
fmt.Fprintf(buf,
"\t\t\t\tbuf.WriteVaruint32(uint32(sliceLen))\n")
fmt.Fprintf(buf, "\t\t\t\tif sliceLen > 0 {\n")
- fmt.Fprintf(buf, "\t\t\t\t\t// WriteData collection
flags for dynamic slice []interface{}\n")
+ fmt.Fprintf(buf, "\t\t\t\t\t// WriteData collection
flags for dynamic slice []any\n")
fmt.Fprintf(buf, "\t\t\t\t\t// Only
CollectionTrackingRef is set (no declared type, may have different types)\n")
fmt.Fprintf(buf, "\t\t\t\t\tbuf.WriteInt8(1) //
CollectionTrackingRef only\n")
fmt.Fprintf(buf, "\t\t\t\t\t// WriteData each element
using WriteValue\n")
@@ -202,10 +204,11 @@ func generateFieldWriteTyped(buf *bytes.Buffer, field
*FieldInfo) error {
return nil
}
- // Handle interface types
- if iface, ok := field.Type.(*types.Interface); ok {
+ // Handle interface types (including 'any' which is an alias for
interface{})
+ unwrappedType := types.Unalias(field.Type)
+ if iface, ok := unwrappedType.(*types.Interface); ok {
if iface.Empty() {
- // For interface{}, use WriteValue for dynamic type
handling
+ // For any, use WriteValue for dynamic type handling
fmt.Fprintf(buf, "\tctx.WriteValue(reflect.ValueOf(%s),
fory.RefModeTracking, true)\n", fieldAccess)
return nil
}
@@ -456,13 +459,15 @@ func generateMapWriteInline(buf *bytes.Buffer, mapType
*types.Map, fieldAccess s
keyType := mapType.Key()
valueType := mapType.Elem()
- // Check if key or value types are interface{}
+ // Check if key or value types are any (unwrap aliases like 'any')
keyIsInterface := false
valueIsInterface := false
- if iface, ok := keyType.(*types.Interface); ok && iface.Empty() {
+ unwrappedKey := types.Unalias(keyType)
+ unwrappedValue := types.Unalias(valueType)
+ if iface, ok := unwrappedKey.(*types.Interface); ok && iface.Empty() {
keyIsInterface = true
}
- if iface, ok := valueType.(*types.Interface); ok && iface.Empty() {
+ if iface, ok := unwrappedValue.(*types.Interface); ok && iface.Empty() {
valueIsInterface = true
}
@@ -529,7 +534,7 @@ func writeMapChunksCode(buf *bytes.Buffer, keyType,
valueType types.Type, fieldA
fmt.Fprintf(buf, "%s\t}\n", indent)
}
} else {
- // For interface{} keys, always set not declared type flag
+ // For any keys, always set not declared type flag
fmt.Fprintf(buf, "%s\tkvHeader |= 0x4 // key type not
declared\n", indent)
}
@@ -541,7 +546,7 @@ func writeMapChunksCode(buf *bytes.Buffer, keyType,
valueType types.Type, fieldA
fmt.Fprintf(buf, "%s\t}\n", indent)
}
} else {
- // For interface{} values, always set not declared type flag
+ // For any values, always set not declared type flag
fmt.Fprintf(buf, "%s\tkvHeader |= 0x20 // value type not
declared\n", indent)
}
@@ -783,10 +788,11 @@ func generateSliceElementWriteInline(buf *bytes.Buffer,
elemType types.Type, ele
return nil
}
- // Handle interface types
- if iface, ok := elemType.(*types.Interface); ok {
+ // Handle interface types (including 'any' which is an alias for
interface{})
+ unwrappedElem := types.Unalias(elemType)
+ if iface, ok := unwrappedElem.(*types.Interface); ok {
if iface.Empty() {
- // For interface{} elements, use WriteValue for dynamic
type handling
+ // For any elements, use WriteValue for dynamic type
handling
fmt.Fprintf(buf,
"\t\t\t\tctx.WriteValue(reflect.ValueOf(%s), fory.RefModeTracking, true)\n",
elemAccess)
return nil
}
@@ -830,10 +836,11 @@ func generateSliceElementWriteInlineIndented(buf
*bytes.Buffer, elemType types.T
return nil
}
- // Handle interface types
- if iface, ok := elemType.(*types.Interface); ok {
+ // Handle interface types (including 'any' which is an alias for
interface{})
+ unwrappedElem := types.Unalias(elemType)
+ if iface, ok := unwrappedElem.(*types.Interface); ok {
if iface.Empty() {
- // For interface{} elements, use WriteValue for dynamic
type handling
+ // For any elements, use WriteValue for dynamic type
handling
fmt.Fprintf(buf, "%sctx.WriteValue(reflect.ValueOf(%s),
fory.RefModeTracking, true)\n", indent, elemAccess)
return nil
}
diff --git a/go/fory/codegen/guard.go b/go/fory/codegen/guard.go
index b73aed571..becb1b5f6 100644
--- a/go/fory/codegen/guard.go
+++ b/go/fory/codegen/guard.go
@@ -94,6 +94,18 @@ func formatFieldType(field FieldInfo) string {
// formatGoType converts a Go type to its string representation
func formatGoType(t types.Type) string {
switch type_ := t.(type) {
+ case *types.Alias:
+ // Handle alias types like 'any' (alias for interface{})
+ // Check if it's the 'any' alias specifically
+ if type_.Obj().Name() == "any" {
+ return "any"
+ }
+ // For other aliases, use the alias name if it's from universe
scope,
+ // otherwise format the underlying type
+ if type_.Obj().Pkg() == nil {
+ return type_.Obj().Name()
+ }
+ return formatGoType(types.Unalias(t))
case *types.Basic:
return type_.Name()
case *types.Pointer:
@@ -124,7 +136,7 @@ func formatGoType(t types.Type) string {
return obj.Name()
case *types.Interface:
if type_.Empty() {
- return "interface{}"
+ return "any"
}
// For non-empty interfaces, we need to format method signatures
var methods []string
diff --git a/go/fory/codegen/utils.go b/go/fory/codegen/utils.go
index f562ccf1d..9751e1e7c 100644
--- a/go/fory/codegen/utils.go
+++ b/go/fory/codegen/utils.go
@@ -58,6 +58,9 @@ func toSnakeCase(s string) string {
// isSupportedFieldType checks if a field type is supported
func isSupportedFieldType(t types.Type) bool {
+ // Unwrap alias types (e.g., 'any' is an alias for 'interface{}')
+ t = types.Unalias(t)
+
// Handle pointer types
if ptr, ok := t.(*types.Pointer); ok {
t = ptr.Elem()
@@ -90,7 +93,7 @@ func isSupportedFieldType(t types.Type) bool {
// Check interface types
if iface, ok := t.(*types.Interface); ok {
- // Support empty interface{} for dynamic types
+ // Support empty any for dynamic types
if iface.Empty() {
return true
}
@@ -111,6 +114,9 @@ func isSupportedFieldType(t types.Type) bool {
// isPrimitiveType checks if a type is considered primitive in Fory
func isPrimitiveType(t types.Type) bool {
+ // Unwrap alias types
+ t = types.Unalias(t)
+
// Handle pointer types
if ptr, ok := t.(*types.Pointer); ok {
t = ptr.Elem()
@@ -134,6 +140,9 @@ func isPrimitiveType(t types.Type) bool {
// getTypeID returns the Fory TypeID for a given type
func getTypeID(t types.Type) string {
+ // Unwrap alias types
+ t = types.Unalias(t)
+
// Handle pointer types
if ptr, ok := t.(*types.Pointer); ok {
t = ptr.Elem()
@@ -177,7 +186,7 @@ func getTypeID(t types.Type) string {
// Check interface types
if iface, ok := t.(*types.Interface); ok {
if iface.Empty() {
- return "INTERFACE" // Use a placeholder for empty
interface{}
+ return "INTERFACE" // Use a placeholder for empty any
}
}
@@ -231,6 +240,9 @@ func getTypeID(t types.Type) string {
// getPrimitiveSize returns the byte size of a primitive type
func getPrimitiveSize(t types.Type) int {
+ // Unwrap alias types
+ t = types.Unalias(t)
+
// Handle pointer types
if ptr, ok := t.(*types.Pointer); ok {
t = ptr.Elem()
diff --git a/go/fory/errors.go b/go/fory/errors.go
index 9f8cde95a..73304bced 100644
--- a/go/fory/errors.go
+++ b/go/fory/errors.go
@@ -155,7 +155,7 @@ func SerializationError(msg string) Error {
}
// SerializationErrorf creates a formatted serialization error
-func SerializationErrorf(format string, args ...interface{}) Error {
+func SerializationErrorf(format string, args ...any) Error {
return Error{
kind: ErrKindSerializationFailed,
message: fmt.Sprintf(format, args...),
@@ -171,7 +171,7 @@ func DeserializationError(msg string) Error {
}
// DeserializationErrorf creates a formatted deserialization error
-func DeserializationErrorf(format string, args ...interface{}) Error {
+func DeserializationErrorf(format string, args ...any) Error {
return Error{
kind: ErrKindDeserializationFailed,
message: fmt.Sprintf(format, args...),
@@ -211,7 +211,7 @@ func InvalidTagError(msg string) Error {
}
// InvalidTagErrorf creates a formatted invalid fory struct tag error
-func InvalidTagErrorf(format string, args ...interface{}) Error {
+func InvalidTagErrorf(format string, args ...any) Error {
return Error{
kind: ErrKindInvalidTag,
message: fmt.Sprintf(format, args...),
diff --git a/go/fory/field_info.go b/go/fory/field_info.go
index 5dd9ab356..1ba60b4eb 100644
--- a/go/fory/field_info.go
+++ b/go/fory/field_info.go
@@ -719,7 +719,7 @@ func typesCompatible(actual, expected reflect.Type) bool {
if actual == expected {
return true
}
- // interface{} can accept any value
+ // any can accept any value
if actual.Kind() == reflect.Interface && actual.NumMethod() == 0 {
return true
}
diff --git a/go/fory/fory.go b/go/fory/fory.go
index 26e66017e..bf02cb6e8 100644
--- a/go/fory/fory.go
+++ b/go/fory/fory.go
@@ -205,7 +205,7 @@ func NewFory(opts ...Option) *Fory {
// type_ can be either a reflect.Type or an instance of the type
// typeID should be the user type ID in the range 0-8192 (the internal type ID
will be added automatically)
// Note: For enum types, use RegisterEnum instead.
-func (f *Fory) RegisterStruct(type_ interface{}, typeID uint32) error {
+func (f *Fory) RegisterStruct(type_ any, typeID uint32) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -241,7 +241,7 @@ func (f *Fory) RegisterStruct(type_ interface{}, typeID
uint32) error {
// type_ can be either a reflect.Type or an instance of the type
// typeName can include a namespace prefix separated by "." (e.g.,
"example.Foo")
// Note: For enum types, use RegisterNamedEnum instead.
-func (f *Fory) RegisterNamedStruct(type_ interface{}, typeName string) error {
+func (f *Fory) RegisterNamedStruct(type_ any, typeName string) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -269,7 +269,7 @@ func (f *Fory) RegisterNamedStruct(type_ interface{},
typeName string) error {
// This method creates an enum serializer that writes/reads the enum value as
Varuint32Small7.
// type_ can be either a reflect.Type or an instance of the enum type
// typeID should be the user type ID in the range 0-8192 (the internal type ID
will be added automatically)
-func (f *Fory) RegisterEnum(type_ interface{}, typeID uint32) error {
+func (f *Fory) RegisterEnum(type_ any, typeID uint32) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -299,7 +299,7 @@ func (f *Fory) RegisterEnum(type_ interface{}, typeID
uint32) error {
// In Go, enums are typically defined as int-based types (e.g., type Color
int32).
// type_ can be either a reflect.Type or an instance of the enum type
// typeName can include a namespace prefix separated by "." (e.g.,
"example.Color")
-func (f *Fory) RegisterNamedEnum(type_ interface{}, typeName string) error {
+func (f *Fory) RegisterNamedEnum(type_ any, typeName string) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -332,7 +332,7 @@ func (f *Fory) RegisterNamedEnum(type_ interface{},
typeName string) error {
// RegisterExtension registers a type as an extension type with a numeric ID.
// Extension types use a custom serializer provided by the user.
// typeID should be the user type ID in the range 0-8192.
-func (f *Fory) RegisterExtension(type_ interface{}, typeID uint32, serializer
ExtensionSerializer) error {
+func (f *Fory) RegisterExtension(type_ any, typeID uint32, serializer
ExtensionSerializer) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -353,20 +353,20 @@ func (f *Fory) RegisterExtension(type_ interface{},
typeID uint32, serializer Ex
//
// type MyExtSerializer struct{}
//
-// func (s *MyExtSerializer) Write(buf *ByteBuffer, value interface{})
error {
+// func (s *MyExtSerializer) Write(buf *ByteBuffer, value any) error {
// myExt := value.(MyExt)
// buf.WriteVarint32(myExt.Id)
// return nil
// }
//
-// func (s *MyExtSerializer) Read(buf *ByteBuffer) (interface{}, error) {
+// func (s *MyExtSerializer) Read(buf *ByteBuffer) (any, error) {
// id := buf.ReadVarint32(err)
// return MyExt{Id: id}, nil
// }
//
// // Register with custom serializer
// f.RegisterNamedExtension(MyExt{}, "my_ext", &MyExtSerializer{})
-func (f *Fory) RegisterNamedExtension(type_ interface{}, typeName string,
serializer ExtensionSerializer) error {
+func (f *Fory) RegisterNamedExtension(type_ any, typeName string, serializer
ExtensionSerializer) error {
var t reflect.Type
if rt, ok := type_.(reflect.Type); ok {
t = rt
@@ -441,7 +441,7 @@ func (f *Fory) Serialize(value any) ([]byte, error) {
// Deserialize deserializes data directly into the provided target value.
// The target must be a pointer to the value to deserialize into.
-func (f *Fory) Deserialize(data []byte, v interface{}) error {
+func (f *Fory) Deserialize(data []byte, v any) error {
defer f.resetReadState()
f.readCtx.SetData(data)
@@ -511,7 +511,7 @@ func (f *Fory) resetWriteState() {
// SerializeTo serializes a value and appends the bytes to the provided buffer.
// This is useful when you need to write multiple serialized values to the
same buffer.
// Returns error if serialization fails.
-func (f *Fory) SerializeTo(buf *ByteBuffer, value interface{}) error {
+func (f *Fory) SerializeTo(buf *ByteBuffer, value any) error {
// Handle nil values
if isNilValue(value) {
// Use Java-compatible null format: 3 bytes (magic + bitmap
with isNilFlag)
@@ -590,7 +590,7 @@ finish:
// DeserializeFrom deserializes data from an existing buffer directly into the
provided target value.
// The buffer's reader index is advanced as data is read.
// This is useful when reading multiple serialized values from the same buffer.
-func (f *Fory) DeserializeFrom(buf *ByteBuffer, v interface{}) error {
+func (f *Fory) DeserializeFrom(buf *ByteBuffer, v any) error {
// Reset contexts for each independent serialized object
defer f.resetReadState()
@@ -662,12 +662,12 @@ func (f *Fory) DeserializeFrom(buf *ByteBuffer, v
interface{}) error {
// safeCopy := bytes.Clone(data)
//
// For thread-safe usage, use threadsafe.Fory which copies the data internally.
-func (f *Fory) Marshal(v interface{}) ([]byte, error) {
+func (f *Fory) Marshal(v any) ([]byte, error) {
return f.Serialize(v)
}
// Unmarshal deserializes bytes into the provided value.
-func (f *Fory) Unmarshal(data []byte, v interface{}) error {
+func (f *Fory) Unmarshal(data []byte, v any) error {
return f.Deserialize(data, v)
}
@@ -675,7 +675,7 @@ func (f *Fory) Unmarshal(data []byte, v interface{}) error {
// The third parameter is an optional callback for buffer objects (can be nil).
// If callback is provided, it will be called for each BufferObject during
serialization.
// Return true from callback to write in-band, false for out-of-band.
-func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v interface{},
callback func(BufferObject) bool) error {
+func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v any, callback
func(BufferObject) bool) error {
buf := f.writeCtx.buffer
defer func() {
// Reset internal state but NOT the buffer - caller manages
buffer state
@@ -733,7 +733,7 @@ func (f *Fory) SerializeWithCallback(buffer *ByteBuffer, v
interface{}, callback
// DeserializeWithCallbackBuffers deserializes from buffer into the provided
value (for streaming/cross-language use).
// The third parameter is optional external buffers for out-of-band data (can
be nil).
-func (f *Fory) DeserializeWithCallbackBuffers(buffer *ByteBuffer, v
interface{}, buffers []*ByteBuffer) error {
+func (f *Fory) DeserializeWithCallbackBuffers(buffer *ByteBuffer, v any,
buffers []*ByteBuffer) error {
// Reset context and use the provided buffer
f.readCtx.buffer = buffer
defer func() {
@@ -871,7 +871,7 @@ func writeHeader(ctx *WriteContext, config Config) {
ctx.buffer.WriteByte_(LangGO)
}
-// isNilValue checks if a value is nil, including nil pointers wrapped in
interface{}
+// isNilValue checks if a value is nil, including nil pointers wrapped in any
// In Go, `*int32(nil)` wrapped in `any` is NOT equal to `nil`, but we need to
treat it as null.
func isNilValue(value any) bool {
if value == nil {
diff --git a/go/fory/fory_compatible_test.go b/go/fory/fory_compatible_test.go
index 62ecbb125..6e3e6734e 100644
--- a/go/fory/fory_compatible_test.go
+++ b/go/fory/fory_compatible_test.go
@@ -62,7 +62,7 @@ type MapDataClass struct {
}
type ComplexObject1 struct {
- F1 interface{}
+ F1 any
F2 string
F3 []string
F4 map[int8]int32
@@ -77,7 +77,7 @@ type ComplexObject1 struct {
}
type ComplexObject2 struct {
- F1 interface{}
+ F1 any
F2 map[int8]int32
}
@@ -142,7 +142,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
writeType: SimpleDataClass{},
readType: SimpleDataClass{},
input: SimpleDataClass{Name: "test", Age: 25,
Active: true},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SimpleDataClass)
out := output.(SimpleDataClass)
assert.Equal(t, in.Age, out.Age)
@@ -181,7 +181,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
readerSetup: func(f *Fory) error {
return f.RegisterNamedStruct(ComplexObject2{},
"test.ComplexObject2")
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(ComplexObject1)
out := output.(ComplexObject1)
// Note: F1 may be either ComplexObject2 or
*ComplexObject2 depending on reference tracking
@@ -216,7 +216,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
writeType: SimpleDataClass{},
readType: InconsistentDataClass{},
input: SimpleDataClass{Name: "test", Age: 25,
Active: true},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SimpleDataClass)
out := output.(InconsistentDataClass)
assert.Zero(t, out.Name)
@@ -236,7 +236,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
IntField: 42,
ByteField: 255,
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(UnsortedStruct)
out := output.(UnsortedStruct)
assert.Equal(t, in.FloatField, out.FloatField)
@@ -252,7 +252,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
writeType: SimpleDataClass{},
readType: ExtendedDataClass{},
input: SimpleDataClass{Name: "test", Age: 25,
Active: true},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SimpleDataClass)
out := output.(ExtendedDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -267,7 +267,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
writeType: SimpleDataClass{},
readType: ReducedDataClass{},
input: SimpleDataClass{Name: "test", Age: 25,
Active: true},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SimpleDataClass)
out := output.(ReducedDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -284,7 +284,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
Items: []string{"item1", "item2", "item3"},
Nums: []int32{10, 20, 30, 40},
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SliceDataClass)
out := output.(SliceDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -302,7 +302,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
Items: []string{"item1", "item2"},
Nums: []int32{1, 2, 3},
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(SliceDataClass)
out := output.(InconsistentSliceDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -328,7 +328,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
"success": 95,
},
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(MapDataClass)
out := output.(MapDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -358,7 +358,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
readerSetup: func(f *Fory) error {
return f.RegisterNamedStruct(SimpleDataClass{},
"SimpleDataClass")
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(PointerDataClass)
out := output.(PointerDataClass)
if assert.NotNil(t, out.Inner) {
@@ -386,7 +386,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
readerSetup: func(f *Fory) error {
return
f.RegisterNamedStruct(InconsistentDataClass{}, "SimpleDataClass")
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(PointerDataClass)
out := output.(PointerInconsistentDataClass)
if assert.NotNil(t, out.Inner) {
@@ -412,7 +412,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
"c2": 20,
},
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(MapDataClass)
out := output.(InconsistentMapDataClass)
assert.Equal(t, in.Name, out.Name)
@@ -441,7 +441,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
}
return nil
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(NestedOuter)
out := output.(NestedOuter)
assert.Equal(t, in.Name, out.Name)
@@ -469,7 +469,7 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
}
return nil
},
- assertFunc: func(t *testing.T, input interface{},
output interface{}) {
+ assertFunc: func(t *testing.T, input any, output any) {
in := input.(NestedOuter)
out := output.(NestedOuterIncompatible)
assert.Equal(t, in.Name, out.Name)
@@ -490,10 +490,10 @@ func TestCompatibleSerializationScenarios(t *testing.T) {
type compatibilityCase struct {
name string
tag string
- writeType interface{}
- readType interface{}
- input interface{}
- assertFunc func(t *testing.T, input interface{}, output interface{})
+ writeType any
+ readType any
+ input any
+ assertFunc func(t *testing.T, input any, output any)
writerSetup func(*Fory) error
readerSetup func(*Fory) error
}
diff --git a/go/fory/fory_test.go b/go/fory/fory_test.go
index 6a9a3811f..e42911cb5 100644
--- a/go/fory/fory_test.go
+++ b/go/fory/fory_test.go
@@ -26,8 +26,8 @@ import (
"github.com/stretchr/testify/require"
)
-func primitiveData() []interface{} {
- return []interface{}{
+func primitiveData() []any {
+ return []any{
false,
true,
byte(0),
@@ -62,8 +62,8 @@ func primitiveData() []interface{} {
}
}
-func commonSlice() []interface{} {
- return []interface{}{
+func commonSlice() []any {
+ return []any{
(&[100]bool{})[:],
(&[100]byte{})[:],
// (&[100]int8{})[:],
@@ -76,8 +76,8 @@ func commonSlice() []interface{} {
}
}
-func commonMap() []interface{} {
- return []interface{}{
+func commonMap() []any {
+ return []any{
// TODO: map[string]bool with false values has a pre-existing
serialization bug
// where false values become true after deserialization. Skip
until fixed.
// map[string]bool{"k1": false, "k2": true, "str": true, "":
true},
@@ -99,14 +99,14 @@ func commonMap() []interface{} {
map[int64]int64{1: 1, 2: 2, 3: 3},
map[float32]float32{1: 1, 2: 2, 3: 3},
map[float64]float64{1: 1, 2: 2, 3: 3},
- map[interface{}]interface{}{"k1": "v1", "k2": "v2", "str": "",
"": ""},
- map[string]interface{}{"k1": "v1", "k2": "v2", "str": "", "":
""},
- map[interface{}]string{"k1": "v1", "k2": "v2", "str": "", "":
""},
+ map[any]any{"k1": "v1", "k2": "v2", "str": "", "": ""},
+ map[string]any{"k1": "v1", "k2": "v2", "str": "", "": ""},
+ map[any]string{"k1": "v1", "k2": "v2", "str": "", "": ""},
}
}
-func commonArray() []interface{} {
- return []interface{}{
+func commonArray() []any {
+ return []any{
[100]bool{false, true, true},
[100]byte{1, 2, 3},
// [100]int8{1, 2, 3},
@@ -131,13 +131,13 @@ func TestSerializePrimitives(t *testing.T) {
func TestSerializeInterface(t *testing.T) {
for _, referenceTracking := range []bool{false, true} {
fory := NewFory(WithXlang(true),
WithRefTracking(referenceTracking))
- var a interface{}
+ var a any
a = -1
serde(t, fory, a)
// Use int64 for interface values since fory deserializes
integers to int64 for cross-language compatibility
- b := []interface{}{int64(1), int64(2), "str"}
+ b := []any{int64(1), int64(2), "str"}
serde(t, fory, b)
- var newB []interface{}
+ var newB []any
serDeserializeTo(t, fory, b, &newB)
require.Equal(t, b, newB)
// pointer to interface is not allowed.
@@ -173,7 +173,7 @@ func TestSerializeSlice(t *testing.T) {
serde(t, fory, []float32{-1.0, 0, 1.0})
serde(t, fory, []float64{-1.0, 0, 1.0})
serde(t, fory, []string{"str1", "", "str2"})
- serde(t, fory, []interface{}{"", "", "str", "str"})
+ serde(t, fory, []any{"", "", "str", "str"})
serde(t, fory, primitiveData())
for _, data := range commonSlice() {
serde(t, fory, data)
@@ -188,11 +188,11 @@ func TestSerializeMap(t *testing.T) {
// "str1" is deserialized by interface type, which will be set
to map key whose type is string.
// so we need to save interface dynamic value type instead of
interface value in reference resolver.
{
- value := []interface{}{"str1",
map[string]interface{}{"str1": "str2"}}
+ value := []any{"str1", map[string]any{"str1": "str2"}}
serde(t, fory, value)
}
{
- value := map[string]interface{}{"k1": "v1", "str": "",
"": ""}
+ value := map[string]any{"k1": "v1", "str": "", "": ""}
serde(t, fory, value)
}
{
@@ -360,12 +360,12 @@ func TestSerializeStruct(t *testing.T) {
type A struct {
F1 Bar
- F2 interface{}
+ F2 any
}
require.Nil(t, fory.RegisterNamedStruct(A{}, "example.A"))
serde(t, fory, A{})
serde(t, fory, &A{})
- // Use int64 for interface{} fields since xlang deserializes
integers to int64
+ // Use int64 for any fields since xlang deserializes integers
to int64
serde(t, fory, A{F1: Bar{F1: 1, F2: "str"}, F2: int64(-1)})
serde(t, fory, &A{F1: Bar{F1: 1, F2: "str"}, F2: int64(-1)})
@@ -459,14 +459,14 @@ func TestSerializeComplexReference(t *testing.T) {
func TestSerializeCommonReference(t *testing.T) {
fory := NewFory(WithXlang(true), WithRefTracking(true))
- var values []interface{}
+ var values []any
values = append(values, commonSlice()...)
values = append(values, commonMap()...)
for _, data := range values {
- value := []interface{}{data, data}
+ value := []any{data, data}
bytes, err := fory.Marshal(value)
require.Nil(t, err)
- var newValue []interface{}
+ var newValue []any
require.Nil(t, fory.Unmarshal(bytes, &newValue))
require.Equal(t,
unsafe.Pointer(reflect.ValueOf(newValue[0]).Pointer()),
unsafe.Pointer(reflect.ValueOf(newValue[1]).Pointer()))
@@ -479,7 +479,7 @@ func TestSerializeCommonReference(t *testing.T) {
/*
func TestSerializeZeroCopy(t *testing.T) {
fory := NewFory(WithXlang(true), WithRefTracking(true))
- list := []interface{}{"str", make([]byte, 1000)}
+ list := []any{"str", make([]byte, 1000)}
buf := NewByteBuffer(nil)
var bufferObjects []BufferObject
require.Nil(t, fory.SerializeWithCallback(buf, list, func(o
BufferObject) bool {
@@ -487,7 +487,7 @@ func TestSerializeZeroCopy(t *testing.T) {
return false
}))
require.Equal(t, 1, len(bufferObjects))
- var newList []interface{}
+ var newList []any
var buffers []*ByteBuffer
for _, o := range bufferObjects {
buffers = append(buffers, o.ToBuffer())
@@ -498,7 +498,7 @@ func TestSerializeZeroCopy(t *testing.T) {
}
*/
-func serDeserializeTo(t *testing.T, fory *Fory, value interface{}, to
interface{}) {
+func serDeserializeTo(t *testing.T, fory *Fory, value any, to any) {
bytes, err := fory.Marshal(value)
require.Nil(t, err, fmt.Sprintf("serialize value %s with type %s
failed: %s",
reflect.ValueOf(value), reflect.TypeOf(value), err))
@@ -508,11 +508,11 @@ func serDeserializeTo(t *testing.T, fory *Fory, value
interface{}, to interface{
require.Equal(t, value, reflect.ValueOf(to).Elem().Interface())
}
-func serde(t *testing.T, fory *Fory, value interface{}) {
+func serde(t *testing.T, fory *Fory, value any) {
bytes, err := fory.Marshal(value)
require.Nil(t, err, fmt.Sprintf("serialize value %s with type %s
failed: %s",
reflect.ValueOf(value), reflect.TypeOf(value), err))
- var newValue interface{}
+ var newValue any
require.Nil(t, fory.Unmarshal(bytes, &newValue), "deserialize value %s
with type %s failed: %s",
fmt.Sprintf("deserialize value %s with type %s failed: %s",
reflect.ValueOf(value), reflect.TypeOf(value), err))
@@ -571,7 +571,7 @@ func BenchmarkUnmarshal(b *testing.B) {
panic(err)
}
for i := 0; i < b.N; i++ {
- var newFoo interface{}
+ var newFoo any
err := fory.Unmarshal(data, &newFoo)
if err != nil {
panic(err)
@@ -579,7 +579,7 @@ func BenchmarkUnmarshal(b *testing.B) {
}
}
-func benchData() interface{} {
+func benchData() any {
var strData []byte
for i := 0; i < 1000; i++ {
strData = append(strData, 100)
@@ -590,19 +590,19 @@ func benchData() interface{} {
func ExampleFory_Serialize() {
f := New(WithXlang(true))
- list := []interface{}{true, false, "str", -1.1, 1, make([]int32, 5),
make([]float64, 5)}
+ list := []any{true, false, "str", -1.1, 1, make([]int32, 5),
make([]float64, 5)}
bytes, err := f.Serialize(list)
if err != nil {
panic(err)
}
// bytes can be data serialized by other languages.
- var newValue interface{}
+ var newValue any
if err = f.Deserialize(bytes, &newValue); err != nil {
panic(err)
}
fmt.Println(newValue)
- dict := map[string]interface{}{
+ dict := map[string]any{
"k1": "v1",
"k2": list,
"k3": -1,
@@ -693,17 +693,17 @@ func TestStructWithNestedSlice(t *testing.T) {
{Name: "test"},
}}
bytes, _ := fory.Marshal(example)
- var deserialized2 interface{}
+ var deserialized2 any
if err := fory.Unmarshal(bytes, &deserialized2); err != nil {
panic(err)
}
- // When unmarshaling to interface{}, named structs are returned as
pointers
+ // When unmarshaling to any, named structs are returned as pointers
// for circular reference support
require.Equal(t, deserialized2, example)
}
func convertRecursively(newVal, tmplVal reflect.Value) (reflect.Value, error) {
- // Unwrap any interface{}
+ // Unwrap any any
if newVal.Kind() == reflect.Interface && !newVal.IsNil() {
newVal = newVal.Elem()
}
@@ -797,7 +797,7 @@ func convertRecursively(newVal, tmplVal reflect.Value)
(reflect.Value, error) {
}
return out, nil
default:
- // Handle pointer-to-value conversion (common when
deserializing named structs into interface{})
+ // Handle pointer-to-value conversion (common when
deserializing named structs into any)
if newVal.Kind() == reflect.Ptr && tmplVal.Kind() ==
reflect.Struct {
if !newVal.IsNil() && newVal.Elem().Type() ==
tmplVal.Type() {
return newVal.Elem(), nil
diff --git a/go/fory/map.go b/go/fory/map.go
index cf2f12ae0..78dd927c7 100644
--- a/go/fory/map.go
+++ b/go/fory/map.go
@@ -296,9 +296,9 @@ func (s mapSerializer) ReadData(ctx *ReadContext, value
reflect.Value) {
// Initialize map
if value.IsNil() {
mapType := type_
- // For interface{} maps without declared types, use
map[interface{}]interface{}
+ // For any maps without declared types, use map[any]any
if !s.hasGenerics && type_.Key().Kind() == reflect.Interface &&
type_.Elem().Kind() == reflect.Interface {
- iface := reflect.TypeOf((*interface{})(nil)).Elem()
+ iface := reflect.TypeOf((*any)(nil)).Elem()
mapType = reflect.MapOf(iface, iface)
}
value.Set(reflect.MakeMap(mapType))
diff --git a/go/fory/reader.go b/go/fory/reader.go
index bb034edad..2eeefe3d8 100644
--- a/go/fory/reader.go
+++ b/go/fory/reader.go
@@ -570,7 +570,7 @@ func (c *ReadContext) ReadValue(value reflect.Value,
refMode RefMode, readType b
return
}
- // For interface{} types, we need to read the actual type from the
buffer first
+ // For any types, we need to read the actual type from the buffer first
if value.Type().Kind() == reflect.Interface {
// Handle ref tracking based on refMode
var refID int32 = int32(NotNullValueFlag)
@@ -598,7 +598,7 @@ func (c *ReadContext) ReadValue(value reflect.Value,
refMode RefMode, readType b
// Read type info to determine the actual type
if !readType {
- c.SetError(DeserializationError("cannot read
interface{} without type info"))
+ c.SetError(DeserializationError("cannot read any
without type info"))
return
}
ctxErr := c.Err()
@@ -625,7 +625,7 @@ func (c *ReadContext) ReadValue(value reflect.Value,
refMode RefMode, readType b
// For named struct types, create a pointer type to support
circular references.
// In Java/xlang serialization, objects are always by
reference, so when deserializing
- // into interface{}, we need to use pointers to maintain
reference semantics.
+ // into any, we need to use pointers to maintain reference
semantics.
isNamedStruct := actualType.Kind() == reflect.Struct &&
(internalTypeID == NAMED_STRUCT || internalTypeID ==
NAMED_COMPATIBLE_STRUCT ||
internalTypeID == COMPATIBLE_STRUCT ||
internalTypeID == STRUCT)
diff --git a/go/fory/ref_resolver_test.go b/go/fory/ref_resolver_test.go
index aed8e92e4..f73880e56 100644
--- a/go/fory/ref_resolver_test.go
+++ b/go/fory/ref_resolver_test.go
@@ -28,7 +28,7 @@ import (
func TestReferenceResolver(t *testing.T) {
refResolver := newRefResolver(true)
buf := NewByteBuffer(nil)
- var values []interface{}
+ var values []any
values = append(values, commonSlice()...)
values = append(values, commonMap()...)
foo := newFoo()
@@ -67,7 +67,7 @@ func TestReferenceResolver(t *testing.T) {
func TestNonReferenceResolver(t *testing.T) {
refResolver := newRefResolver(false)
buf := NewByteBuffer(nil)
- var values []interface{}
+ var values []any
values = append(values, commonSlice()...)
values = append(values, commonMap()...)
foo := newFoo()
@@ -89,7 +89,7 @@ func TestNonReferenceResolver(t *testing.T) {
}
func TestNullable(t *testing.T) {
- var values []interface{}
+ var values []any
values = append(values, commonSlice()...)
values = append(values, commonMap()...)
foo := newFoo()
@@ -104,11 +104,11 @@ func TestNullable(t *testing.T) {
var v2 map[string]int
require.True(t, isNil(reflect.ValueOf(v2)))
require.False(t, isNil(reflect.ValueOf("")))
- var v3 interface{}
+ var v3 any
require.True(t, isNil(reflect.ValueOf(v3)))
}
-func same(x, y interface{}) bool {
+func same(x, y any) bool {
var vx, vy = reflect.ValueOf(x), reflect.ValueOf(y)
if vx.Type() != vy.Type() {
return false
diff --git a/go/fory/skip.go b/go/fory/skip.go
index 9aa1a14d5..3f300fa53 100644
--- a/go/fory/skip.go
+++ b/go/fory/skip.go
@@ -60,7 +60,7 @@ func SkipFieldValueWithTypeFlag(ctx *ReadContext, fieldDef
FieldDef, readRefFlag
serializer :=
ctx.TypeResolver().getSerializerByTypeID(wroteTypeID)
if serializer != nil {
// Use the serializer to read and discard the
value
- var dummy interface{}
+ var dummy any
dummyVal := reflect.ValueOf(&dummy).Elem()
serializer.Read(ctx, RefModeNone, false, false,
dummyVal)
return
@@ -75,7 +75,7 @@ func SkipFieldValueWithTypeFlag(ctx *ReadContext, fieldDef
FieldDef, readRefFlag
typeInfo :=
ctx.TypeResolver().readTypeInfoWithTypeID(ctx.buffer, wroteTypeID, err)
if typeInfo.Serializer != nil {
// Use the serializer to read and discard the
value
- var dummy interface{}
+ var dummy any
dummyVal := reflect.ValueOf(&dummy).Elem()
typeInfo.Serializer.Read(ctx, RefModeNone,
false, false, dummyVal)
return
@@ -555,7 +555,7 @@ func skipValue(ctx *ReadContext, fieldDef FieldDef,
readRefFlag bool, isField bo
if serializer != nil {
// Use the serializer to read and discard the
value
// Create a dummy value to read into
- var dummy interface{}
+ var dummy any
dummyVal := reflect.ValueOf(&dummy).Elem()
serializer.Read(ctx, RefModeNone, false, false,
dummyVal)
return
diff --git a/go/fory/slice_dyn.go b/go/fory/slice_dyn.go
index 8d5f250d1..3ac95ebe7 100644
--- a/go/fory/slice_dyn.go
+++ b/go/fory/slice_dyn.go
@@ -25,7 +25,7 @@ import (
// sliceDynSerializer provides the dynamic slice implementation that inspects
// element values at runtime.
// This serializer is designed for slices with any interface element type
-// (e.g., []interface{}, []io.Reader, []fmt.Stringer, or pointers to
interfaces).
+// (e.g., []any, []io.Reader, []fmt.Stringer, or pointers to interfaces).
// For slices with concrete element types, use sliceSerializer instead.
type sliceDynSerializer struct {
elemType reflect.Type
@@ -37,7 +37,7 @@ type sliceDynSerializer struct {
// This serializer is ONLY for slices with interface or pointer to interface
element types.
// For other slice types, use sliceSerializer instead.
func newSliceDynSerializer(elemType reflect.Type) (sliceDynSerializer, error) {
- // Nil element type is allowed for fully dynamic slices (e.g.,
[]interface{})
+ // Nil element type is allowed for fully dynamic slices (e.g., []any)
if elemType == nil {
return sliceDynSerializer{
isInterfaceElem: true,
diff --git a/go/fory/struct.go b/go/fory/struct.go
index a73d36319..4a5688839 100644
--- a/go/fory/struct.go
+++ b/go/fory/struct.go
@@ -154,7 +154,7 @@ func (s *structSerializer) initFields(typeResolver
*TypeResolver) error {
fieldType := field.Type
var fieldSerializer Serializer
- // For interface{} fields, don't get a serializer - use
WriteValue/ReadValue instead
+ // For any fields, don't get a serializer - use
WriteValue/ReadValue instead
// which will handle polymorphic types dynamically
if fieldType.Kind() != reflect.Interface {
// Get serializer for all non-interface field types
@@ -372,7 +372,7 @@ func (s *structSerializer) initFields(typeResolver
*TypeResolver) error {
func (s *structSerializer) initFieldsFromTypeDef(typeResolver *TypeResolver)
error {
type_ := s.type_
if type_ == nil {
- // Type is not known - we'll create an interface{} placeholder
+ // Type is not known - we'll create an any placeholder
// This happens when deserializing unknown types in compatible
mode
// For now, we'll create fields that discard all data
var fields []FieldInfo
@@ -381,7 +381,7 @@ func (s *structSerializer)
initFieldsFromTypeDef(typeResolver *TypeResolver) err
remoteTypeInfo, _ :=
def.fieldType.getTypeInfoWithResolver(typeResolver)
remoteType := remoteTypeInfo.Type
if remoteType == nil {
- remoteType =
reflect.TypeOf((*interface{})(nil)).Elem()
+ remoteType = reflect.TypeOf((*any)(nil)).Elem()
}
// Get TypeId from FieldType's TypeId method
fieldTypeId := def.fieldType.TypeId()
@@ -480,8 +480,8 @@ func (s *structSerializer)
initFieldsFromTypeDef(typeResolver *TypeResolver) err
remoteTypeInfo, _ :=
def.fieldType.getTypeInfoWithResolver(typeResolver)
remoteType := remoteTypeInfo.Type
// Track if type lookup failed - we'll need to skip such fields
- // Note: DynamicFieldType.getTypeInfoWithResolver returns
interface{} (not nil) when lookup fails
- emptyInterfaceType := reflect.TypeOf((*interface{})(nil)).Elem()
+ // Note: DynamicFieldType.getTypeInfoWithResolver returns any
(not nil) when lookup fails
+ emptyInterfaceType := reflect.TypeOf((*any)(nil)).Elem()
typeLookupFailed := remoteType == nil || remoteType ==
emptyInterfaceType
if remoteType == nil {
remoteType = emptyInterfaceType
@@ -543,7 +543,7 @@ func (s *structSerializer)
initFieldsFromTypeDef(typeResolver *TypeResolver) err
_, isEnumField =
fieldSerializer.(*enumSerializer)
}
if isPolymorphicField && localType.Kind() ==
reflect.Interface {
- // For polymorphic (UNKNOWN) fields with
interface{} local type,
+ // For polymorphic (UNKNOWN) fields with any
local type,
// allow reading - the actual type will be
determined at runtime
shouldRead = true
fieldType = localType
diff --git a/go/fory/struct_test.go b/go/fory/struct_test.go
index 02253d095..0bd3dff32 100644
--- a/go/fory/struct_test.go
+++ b/go/fory/struct_test.go
@@ -24,14 +24,6 @@ import (
"github.com/stretchr/testify/require"
)
-// Test struct for compatible mode tests (must be named struct at package
level)
-type SetFieldCompatibleTestStruct struct {
- SetField Set[string]
- NullableSet Set[string] `fory:"nullable"`
- MapField map[string]bool
- NullableMap map[string]bool `fory:"nullable"`
-}
-
func TestUnsignedTypeSerialization(t *testing.T) {
type TestStruct struct {
U32Var uint32 `fory:"compress=true"`
@@ -57,7 +49,7 @@ func TestUnsignedTypeSerialization(t *testing.T) {
t.Fatalf("Serialize failed: %v", err)
}
- var result interface{}
+ var result any
err = f.Deserialize(data, &result)
if err != nil {
t.Fatalf("Deserialize failed: %v", err)
@@ -81,22 +73,21 @@ func TestUnsignedTypeSerialization(t *testing.T) {
}
}
-func TestSetField(t *testing.T) {
- type TestStruct struct {
- F1 Set[int32]
- }
-
- f := New(WithXlang(true), WithCompatible(false))
- require.Nil(t, f.RegisterStruct(TestStruct{}, 1), "register struct
error")
+// Test struct for compatible mode tests (must be named struct at package
level)
+type SetFieldsStruct struct {
+ SetField Set[string]
+ NullableSet Set[string] `fory:"nullable"`
+ MapField map[string]bool
+ NullableMap map[string]bool `fory:"nullable"`
}
func TestSetFieldSerializationSchemaConsistent(t *testing.T) {
f := New(WithXlang(true), WithCompatible(false))
- err := f.RegisterStruct(SetFieldCompatibleTestStruct{}, 1001)
+ err := f.RegisterStruct(SetFieldsStruct{}, 1001)
require.NoError(t, err, "register struct error")
// Create test object with Set and Map fields
- obj := SetFieldCompatibleTestStruct{
+ obj := SetFieldsStruct{
SetField: NewSet[string](),
NullableSet: NewSet[string](),
MapField: map[string]bool{"key1": true, "key2": true},
@@ -111,11 +102,11 @@ func TestSetFieldSerializationSchemaConsistent(t
*testing.T) {
t.Logf("Serialized %d bytes", len(data))
// Deserialize
- var result interface{}
+ var result any
err = f.Deserialize(data, &result)
require.NoError(t, err, "Deserialize failed")
- resultObj := result.(*SetFieldCompatibleTestStruct)
+ resultObj := result.(*SetFieldsStruct)
// Verify SetField
require.Equal(t, 2, len(resultObj.SetField), "SetField length mismatch")
@@ -139,11 +130,11 @@ func TestSetFieldSerializationSchemaConsistent(t
*testing.T) {
func TestSetFieldSerializationCompatible(t *testing.T) {
f := New(WithXlang(true), WithCompatible(true))
- err := f.RegisterStruct(SetFieldCompatibleTestStruct{}, 1002)
+ err := f.RegisterStruct(SetFieldsStruct{}, 1002)
require.NoError(t, err, "register struct error")
// Create test object with Set and Map fields
- obj := SetFieldCompatibleTestStruct{
+ obj := SetFieldsStruct{
SetField: NewSet[string](),
NullableSet: NewSet[string](),
MapField: map[string]bool{"key1": true, "key2": true},
@@ -158,11 +149,11 @@ func TestSetFieldSerializationCompatible(t *testing.T) {
t.Logf("Serialized %d bytes", len(data))
// Deserialize
- var result interface{}
+ var result any
err = f.Deserialize(data, &result)
require.NoError(t, err, "Deserialize failed")
- resultObj := result.(*SetFieldCompatibleTestStruct)
+ resultObj := result.(*SetFieldsStruct)
// Verify SetField
require.Equal(t, 2, len(resultObj.SetField), "SetField length mismatch")
diff --git a/go/fory/tests/generator_test.go b/go/fory/tests/generator_test.go
index bbfbf5526..893f71886 100644
--- a/go/fory/tests/generator_test.go
+++ b/go/fory/tests/generator_test.go
@@ -96,9 +96,9 @@ func TestSliceDemo(t *testing.T) {
}
func TestDynamicSliceDemo(t *testing.T) {
- // 1. Create test instance with various interface{} types
+ // 1. Create test instance with various any types
original := &DynamicSliceDemo{
- DynamicSlice: []interface{}{
+ DynamicSlice: []any{
int32(42),
"hello",
float64(3.14),
@@ -158,7 +158,7 @@ func TestDynamicSliceDemoWithNilAndEmpty(t *testing.T) {
// Test with empty slice
originalEmpty := &DynamicSliceDemo{
- DynamicSlice: []interface{}{}, // empty slice
+ DynamicSlice: []any{}, // empty slice
}
dataEmpty, err := f.Marshal(originalEmpty)
diff --git a/go/fory/tests/generator_xlang_test.go
b/go/fory/tests/generator_xlang_test.go
index 9adf3e644..3584f0464 100644
--- a/go/fory/tests/generator_xlang_test.go
+++ b/go/fory/tests/generator_xlang_test.go
@@ -180,7 +180,7 @@ func TestDynamicSliceDemoXlang(t *testing.T) {
// Create test data with simpler types to avoid reflection issues
// Use int64 for interface values since fory deserializes integers to
int64 for cross-language compatibility
codegenInstance := &DynamicSliceDemo{
- DynamicSlice: []interface{}{
+ DynamicSlice: []any{
"first",
int64(200), // Testing mixed types in dynamic slice
"third",
@@ -189,11 +189,11 @@ func TestDynamicSliceDemoXlang(t *testing.T) {
// Define equivalent struct using reflection
type ReflectDynamicStruct struct {
- DynamicSlice []interface{} `json:"dynamic_slice"`
+ DynamicSlice []any `json:"dynamic_slice"`
}
reflectInstance := &ReflectDynamicStruct{
- DynamicSlice: []interface{}{
+ DynamicSlice: []any{
"first",
int64(200), // Testing mixed types in dynamic slice
"third",
diff --git a/go/fory/tests/structs.go b/go/fory/tests/structs.go
index baf8d2e2b..dbceb3861 100644
--- a/go/fory/tests/structs.go
+++ b/go/fory/tests/structs.go
@@ -43,7 +43,7 @@ type SliceDemo struct {
// DynamicSliceDemo is a struct for testing dynamic slice serialization
// fory:generate
type DynamicSliceDemo struct {
- DynamicSlice []interface{} // slice of interface{}
+ DynamicSlice []any // slice of any
}
// MapDemo demonstrates map field support
diff --git a/go/fory/tests/structs_fory_gen.go
b/go/fory/tests/structs_fory_gen.go
index 154623c65..2d1c37eb5 100644
--- a/go/fory/tests/structs_fory_gen.go
+++ b/go/fory/tests/structs_fory_gen.go
@@ -1,6 +1,6 @@
// Code generated by forygen. DO NOT EDIT.
// source: structs.go
-// generated at: 2026-01-09T19:15:47+08:00
+// generated at: 2026-01-12T15:29:28+08:00
package fory
@@ -68,8 +68,8 @@ func (g *DynamicSliceDemo_ForyGenSerializer) WriteTyped(ctx
*fory.WriteContext,
buf.WriteInt32(g.structHash)
// WriteData fields in sorted order
- // Field: DynamicSlice ([]interface{})
- // Dynamic slice []interface{} handling - manual serialization
+ // Field: DynamicSlice ([]any)
+ // Dynamic slice []any handling - manual serialization
{
isXlang := ctx.TypeResolver().IsXlang()
if isXlang {
@@ -80,7 +80,7 @@ func (g *DynamicSliceDemo_ForyGenSerializer) WriteTyped(ctx
*fory.WriteContext,
}
buf.WriteVaruint32(uint32(sliceLen))
if sliceLen > 0 {
- // WriteData collection flags for dynamic slice
[]interface{}
+ // WriteData collection flags for dynamic slice
[]any
// Only CollectionTrackingRef is set (no
declared type, may have different types)
buf.WriteInt8(1) // CollectionTrackingRef only
// WriteData each element using WriteValue
@@ -97,7 +97,7 @@ func (g *DynamicSliceDemo_ForyGenSerializer) WriteTyped(ctx
*fory.WriteContext,
sliceLen := len(v.DynamicSlice)
buf.WriteVaruint32(uint32(sliceLen))
if sliceLen > 0 {
- // WriteData collection flags for
dynamic slice []interface{}
+ // WriteData collection flags for
dynamic slice []any
// Only CollectionTrackingRef is set
(no declared type, may have different types)
buf.WriteInt8(1) //
CollectionTrackingRef only
// WriteData each element using
WriteValue
@@ -174,20 +174,20 @@ func (g *DynamicSliceDemo_ForyGenSerializer)
ReadTyped(ctx *fory.ReadContext, v
}
// ReadData fields in same order as write
- // Field: DynamicSlice ([]interface{})
- // Dynamic slice []interface{} handling - manual deserialization
+ // Field: DynamicSlice ([]any)
+ // Dynamic slice []any handling - manual deserialization
{
isXlang := ctx.TypeResolver().IsXlang()
if isXlang {
// xlang mode: slices are not nullable, read directly
without null flag
sliceLen := int(buf.ReadVaruint32(err))
if sliceLen == 0 {
- v.DynamicSlice = make([]interface{}, 0)
+ v.DynamicSlice = make([]any, 0)
} else {
// ReadData collection flags (ignore for now)
_ = buf.ReadInt8(err)
// Create slice with proper capacity
- v.DynamicSlice = make([]interface{}, sliceLen)
+ v.DynamicSlice = make([]any, sliceLen)
// ReadData each element using ReadValue
for i := range v.DynamicSlice {
ctx.ReadValue(reflect.ValueOf(&v.DynamicSlice[i]).Elem(), fory.RefModeTracking,
true)
@@ -201,12 +201,12 @@ func (g *DynamicSliceDemo_ForyGenSerializer)
ReadTyped(ctx *fory.ReadContext, v
} else {
sliceLen := int(buf.ReadVaruint32(err))
if sliceLen == 0 {
- v.DynamicSlice = make([]interface{}, 0)
+ v.DynamicSlice = make([]any, 0)
} else {
// ReadData collection flags (ignore
for now)
_ = buf.ReadInt8(err)
// Create slice with proper capacity
- v.DynamicSlice = make([]interface{},
sliceLen)
+ v.DynamicSlice = make([]any, sliceLen)
// ReadData each element using ReadValue
for i := range v.DynamicSlice {
ctx.ReadValue(reflect.ValueOf(&v.DynamicSlice[i]).Elem(), fory.RefModeTracking,
true)
@@ -230,7 +230,7 @@ func (g *DynamicSliceDemo_ForyGenSerializer) ReadData(ctx
*fory.ReadContext, val
var v *DynamicSliceDemo
if value.Kind() == reflect.Ptr {
if value.IsNil() {
- // For pointer types, allocate using type_.Elem()
+ // For pointer types, allocate using value.Type().Elem()
value.Set(reflect.New(value.Type().Elem()))
}
v = value.Interface().(*DynamicSliceDemo)
@@ -853,7 +853,7 @@ func (g *MapDemo_ForyGenSerializer) ReadData(ctx
*fory.ReadContext, value reflec
var v *MapDemo
if value.Kind() == reflect.Ptr {
if value.IsNil() {
- // For pointer types, allocate using type_.Elem()
+ // For pointer types, allocate using value.Type().Elem()
value.Set(reflect.New(value.Type().Elem()))
}
v = value.Interface().(*MapDemo)
@@ -1226,7 +1226,7 @@ func (g *SliceDemo_ForyGenSerializer) ReadData(ctx
*fory.ReadContext, value refl
var v *SliceDemo
if value.Kind() == reflect.Ptr {
if value.IsNil() {
- // For pointer types, allocate using type_.Elem()
+ // For pointer types, allocate using value.Type().Elem()
value.Set(reflect.New(value.Type().Elem()))
}
v = value.Interface().(*SliceDemo)
@@ -1398,7 +1398,7 @@ func (g *ValidationDemo_ForyGenSerializer) ReadData(ctx
*fory.ReadContext, value
var v *ValidationDemo
if value.Kind() == reflect.Ptr {
if value.IsNil() {
- // For pointer types, allocate using type_.Elem()
+ // For pointer types, allocate using value.Type().Elem()
value.Set(reflect.New(value.Type().Elem()))
}
v = value.Interface().(*ValidationDemo)
@@ -1422,7 +1422,7 @@ func (g *ValidationDemo_ForyGenSerializer)
ReadWithTypeInfo(ctx *fory.ReadContex
// Snapshot of DynamicSliceDemo's underlying type at generation time.
type _DynamicSliceDemo_expected struct {
- DynamicSlice []interface{}
+ DynamicSlice []any
}
// Compile-time check: this conversion is legal only if DynamicSliceDemo's
underlying type
diff --git a/go/fory/tests/xlang/xlang_test_main.go
b/go/fory/tests/xlang/xlang_test_main.go
index 6cd1650df..47907411c 100644
--- a/go/fory/tests/xlang/xlang_test_main.go
+++ b/go/fory/tests/xlang/xlang_test_main.go
@@ -55,7 +55,7 @@ func writeFile(path string, data []byte) {
}
}
-func assertEqual(expected, actual interface{}, name string) {
+func assertEqual(expected, actual any, name string) {
if expected != actual {
panic(fmt.Sprintf("%s: expected %v, got %v", name, expected,
actual))
}
@@ -64,7 +64,7 @@ func assertEqual(expected, actual interface{}, name string) {
// getStructValue extracts the struct value from either a struct or a pointer
to struct.
// This handles the case where deserialization may return either type
depending on
// reference tracking settings.
-func getOneStringFieldStruct(obj interface{}) OneStringFieldStruct {
+func getOneStringFieldStruct(obj any) OneStringFieldStruct {
switch v := obj.(type) {
case OneStringFieldStruct:
return v
@@ -75,7 +75,7 @@ func getOneStringFieldStruct(obj interface{})
OneStringFieldStruct {
}
}
-func getTwoStringFieldStruct(obj interface{}) TwoStringFieldStruct {
+func getTwoStringFieldStruct(obj any) TwoStringFieldStruct {
switch v := obj.(type) {
case TwoStringFieldStruct:
return v
@@ -86,7 +86,7 @@ func getTwoStringFieldStruct(obj interface{})
TwoStringFieldStruct {
}
}
-func getOneEnumFieldStruct(obj interface{}) OneEnumFieldStruct {
+func getOneEnumFieldStruct(obj any) OneEnumFieldStruct {
switch v := obj.(type) {
case OneEnumFieldStruct:
return v
@@ -97,7 +97,7 @@ func getOneEnumFieldStruct(obj interface{})
OneEnumFieldStruct {
}
}
-func getTwoEnumFieldStruct(obj interface{}) TwoEnumFieldStruct {
+func getTwoEnumFieldStruct(obj any) TwoEnumFieldStruct {
switch v := obj.(type) {
case TwoEnumFieldStruct:
return v
@@ -108,7 +108,7 @@ func getTwoEnumFieldStruct(obj interface{})
TwoEnumFieldStruct {
}
}
-func getNullableComprehensiveSchemaConsistent(obj interface{})
NullableComprehensiveSchemaConsistent {
+func getNullableComprehensiveSchemaConsistent(obj any)
NullableComprehensiveSchemaConsistent {
switch v := obj.(type) {
case NullableComprehensiveSchemaConsistent:
return v
@@ -119,7 +119,7 @@ func getNullableComprehensiveSchemaConsistent(obj
interface{}) NullableComprehen
}
}
-func getNullableComprehensiveCompatible(obj interface{})
NullableComprehensiveCompatible {
+func getNullableComprehensiveCompatible(obj any)
NullableComprehensiveCompatible {
switch v := obj.(type) {
case NullableComprehensiveCompatible:
return v
@@ -130,7 +130,7 @@ func getNullableComprehensiveCompatible(obj interface{})
NullableComprehensiveCo
}
}
-func getUnsignedSchemaConsistent(obj interface{}) UnsignedSchemaConsistent {
+func getUnsignedSchemaConsistent(obj any) UnsignedSchemaConsistent {
switch v := obj.(type) {
case UnsignedSchemaConsistent:
return v
@@ -141,7 +141,7 @@ func getUnsignedSchemaConsistent(obj interface{})
UnsignedSchemaConsistent {
}
}
-func getUnsignedSchemaCompatible(obj interface{}) UnsignedSchemaCompatible {
+func getUnsignedSchemaCompatible(obj any) UnsignedSchemaCompatible {
switch v := obj.(type) {
case UnsignedSchemaCompatible:
return v
@@ -152,7 +152,7 @@ func getUnsignedSchemaCompatible(obj interface{})
UnsignedSchemaCompatible {
}
}
-func getUnsignedSchemaConsistentSimple(obj interface{})
UnsignedSchemaConsistentSimple {
+func getUnsignedSchemaConsistentSimple(obj any) UnsignedSchemaConsistentSimple
{
switch v := obj.(type) {
case UnsignedSchemaConsistentSimple:
return v
@@ -634,10 +634,10 @@ func testCrossLanguageSerializer() {
// Use numeric ID 101 to match Java's fory.register(Color.class, 101)
f.RegisterEnum(Color(0), 101)
- vals := make([]interface{}, 0)
+ vals := make([]any, 0)
buf := fory.NewByteBuffer(data)
for buf.ReaderIndex() < len(data) {
- var val interface{}
+ var val any
err := f.DeserializeWithCallbackBuffers(buf, &val, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize at index %d:
%v", len(vals), err))
@@ -709,10 +709,10 @@ func testList() {
f.RegisterStruct(Item{}, 102)
buf := fory.NewByteBuffer(data)
- lists := make([]interface{}, 4)
+ lists := make([]any, 4)
for i := 0; i < 4; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize list %d: %v",
i, err))
@@ -741,10 +741,10 @@ func testMap() {
f.RegisterStruct(Item{}, 102)
buf := fory.NewByteBuffer(data)
- maps := make([]interface{}, 2)
+ maps := make([]any, 2)
for i := 0; i < 2; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize map %d: %v",
i, err))
@@ -846,10 +846,10 @@ func testItem() {
f.RegisterStruct(Item{}, 102)
buf := fory.NewByteBuffer(data)
- items := make([]interface{}, 3)
+ items := make([]any, 3)
for i := 0; i < 3; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize item %d: %v",
i, err))
@@ -878,10 +878,10 @@ func testColor() {
f.RegisterEnum(Color(0), 101)
buf := fory.NewByteBuffer(data)
- colors := make([]interface{}, 4)
+ colors := make([]any, 4)
for i := 0; i < 4; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize color %d: %v",
i, err))
@@ -1033,10 +1033,10 @@ func testConsistentNamed() {
f.RegisterNamedExtension(MyExt{}, "my_ext", &MyExtSerializer{})
buf := fory.NewByteBuffer(data)
- values := make([]interface{}, 9)
+ values := make([]any, 9)
for i := 0; i < 9; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
fmt.Printf("Deserialized value %d: %+v\n", i, obj)
if err != nil {
@@ -1090,10 +1090,10 @@ func testPolymorphicList() {
f.RegisterStruct(AnimalListHolder{}, 304)
buf := fory.NewByteBuffer(data)
- values := make([]interface{}, 2)
+ values := make([]any, 2)
for i := 0; i < 2; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
fmt.Printf("Deserialized: %v", obj)
if err != nil {
@@ -1125,10 +1125,10 @@ func testPolymorphicMap() {
f.RegisterStruct(AnimalMapHolder{}, 305)
buf := fory.NewByteBuffer(data)
- values := make([]interface{}, 2)
+ values := make([]any, 2)
for i := 0; i < 2; i++ {
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize value %d: %v",
i, err))
@@ -1179,7 +1179,7 @@ func testOneFieldStructCompatible() {
}
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1218,7 +1218,7 @@ func testOneFieldStructSchema() {
f.RegisterStruct(OneFieldStruct{}, 200)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1250,7 +1250,7 @@ func testOneStringFieldSchemaConsistent() {
f.RegisterStruct(OneStringFieldStruct{}, 200)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1277,7 +1277,7 @@ func testOneStringFieldCompatible() {
f.RegisterStruct(OneStringFieldStruct{}, 200)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1304,7 +1304,7 @@ func testTwoStringFieldCompatible() {
f.RegisterStruct(TwoStringFieldStruct{}, 201)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1331,7 +1331,7 @@ func testSchemaEvolutionCompatible() {
f.RegisterStruct(EmptyStruct{}, 200)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize as EmptyStruct: %v",
err))
@@ -1356,7 +1356,7 @@ func testSchemaEvolutionCompatibleReverse() {
f.RegisterStruct(TwoStringFieldStruct{}, 200)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize as
TwoStringFieldStruct: %v", err))
@@ -1386,7 +1386,7 @@ func testOneEnumFieldSchemaConsistent() {
f.RegisterStruct(OneEnumFieldStruct{}, 211)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1414,7 +1414,7 @@ func testOneEnumFieldCompatible() {
f.RegisterStruct(OneEnumFieldStruct{}, 211)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1442,7 +1442,7 @@ func testTwoEnumFieldCompatible() {
f.RegisterStruct(TwoEnumFieldStruct{}, 212)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1474,7 +1474,7 @@ func testEnumSchemaEvolutionCompatible() {
f.RegisterStruct(EmptyStruct{}, 211)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize as EmptyStruct: %v",
err))
@@ -1500,7 +1500,7 @@ func testEnumSchemaEvolutionCompatibleReverse() {
f.RegisterStruct(TwoEnumFieldStruct{}, 211)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize as TwoEnumFieldStruct:
%v", err))
@@ -1536,7 +1536,7 @@ func testNullableFieldSchemaConsistentNotNull() {
f.RegisterStruct(NullableComprehensiveSchemaConsistent{}, 401)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1614,7 +1614,7 @@ func testNullableFieldSchemaConsistentNull() {
f.RegisterStruct(NullableComprehensiveSchemaConsistent{}, 401)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1693,7 +1693,7 @@ func testNullableFieldCompatibleNotNull() {
f.RegisterStruct(NullableComprehensiveCompatible{}, 402)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1799,7 +1799,7 @@ func testNullableFieldCompatibleNull() {
f.RegisterStruct(NullableComprehensiveCompatible{}, 402)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -1925,7 +1925,7 @@ type RefOuterCompatible struct {
Inner2 *RefInnerCompatible `fory:"ref,nullable"`
}
-func getRefOuterSchemaConsistent(obj interface{}) RefOuterSchemaConsistent {
+func getRefOuterSchemaConsistent(obj any) RefOuterSchemaConsistent {
switch v := obj.(type) {
case RefOuterSchemaConsistent:
return v
@@ -1936,7 +1936,7 @@ func getRefOuterSchemaConsistent(obj interface{})
RefOuterSchemaConsistent {
}
}
-func getRefOuterCompatible(obj interface{}) RefOuterCompatible {
+func getRefOuterCompatible(obj any) RefOuterCompatible {
switch v := obj.(type) {
case RefOuterCompatible:
return v
@@ -1960,7 +1960,7 @@ type CircularRefStruct struct {
SelfRef *CircularRefStruct `fory:"ref,nullable"`
}
-func getCircularRefStruct(obj interface{}) *CircularRefStruct {
+func getCircularRefStruct(obj any) *CircularRefStruct {
switch v := obj.(type) {
case CircularRefStruct:
return &v
@@ -1984,7 +1984,7 @@ func testRefSchemaConsistent() {
f.RegisterStruct(RefOuterSchemaConsistent{}, 502)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2032,7 +2032,7 @@ func testRefCompatible() {
f.RegisterStruct(RefOuterCompatible{}, 504)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2083,7 +2083,7 @@ func testCircularRefSchemaConsistent() {
f.RegisterStruct(CircularRefStruct{}, 601)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2120,7 +2120,7 @@ func testCircularRefCompatible() {
f.RegisterStruct(CircularRefStruct{}, 602)
buf := fory.NewByteBuffer(data)
- var obj interface{}
+ var obj any
err := f.DeserializeWithCallbackBuffers(buf, &obj, nil)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2220,7 +2220,7 @@ func testUnsignedSchemaConsistentSimple() {
f := fory.New(fory.WithXlang(true), fory.WithCompatible(false))
f.RegisterStruct(UnsignedSchemaConsistentSimple{}, 1)
- var obj interface{}
+ var obj any
err := f.Deserialize(data, &obj)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2252,7 +2252,7 @@ func testUnsignedSchemaConsistent() {
f := fory.New(fory.WithXlang(true), fory.WithCompatible(false))
f.RegisterStruct(UnsignedSchemaConsistent{}, 501)
- var obj interface{}
+ var obj any
err := f.Deserialize(data, &obj)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
@@ -2310,7 +2310,7 @@ func testUnsignedSchemaCompatible() {
f := fory.New(fory.WithXlang(true), fory.WithCompatible(true))
f.RegisterStruct(UnsignedSchemaCompatible{}, 502)
- var obj interface{}
+ var obj any
err := f.Deserialize(data, &obj)
if err != nil {
panic(fmt.Sprintf("Failed to deserialize: %v", err))
diff --git a/go/fory/threadsafe/fory.go b/go/fory/threadsafe/fory.go
index 8ba83cf49..060a2d3aa 100644
--- a/go/fory/threadsafe/fory.go
+++ b/go/fory/threadsafe/fory.go
@@ -55,7 +55,7 @@ func (f *Fory) release(inner *fory.Fory) {
// ============================================================================
// Serialize serializes a value using a pooled Fory instance
-func (f *Fory) Serialize(v interface{}) ([]byte, error) {
+func (f *Fory) Serialize(v any) ([]byte, error) {
inner := f.acquire()
data, err := inner.Marshal(v)
if err != nil {
@@ -70,14 +70,14 @@ func (f *Fory) Serialize(v interface{}) ([]byte, error) {
}
// Deserialize deserializes data into the provided value using a pooled Fory
instance
-func (f *Fory) Deserialize(data []byte, v interface{}) error {
+func (f *Fory) Deserialize(data []byte, v any) error {
inner := f.acquire()
defer f.release(inner)
return inner.Unmarshal(data, v)
}
// RegisterNamedStruct registers a named struct type for cross-language
serialization
-func (f *Fory) RegisterNamedStruct(type_ interface{}, typeName string) error {
+func (f *Fory) RegisterNamedStruct(type_ any, typeName string) error {
inner := f.acquire()
defer f.release(inner)
return inner.RegisterNamedStruct(type_, typeName)
@@ -132,6 +132,6 @@ func Unmarshal[T any](data []byte, target *T) error {
// UnmarshalTo deserializes data into the provided pointer using the global
thread-safe instance.
// This is for non-generic use cases.
-func UnmarshalTo(data []byte, v interface{}) error {
+func UnmarshalTo(data []byte, v any) error {
return globalFory.Deserialize(data, v)
}
diff --git a/go/fory/type_def.go b/go/fory/type_def.go
index d99c084b2..1f64ff9cd 100644
--- a/go/fory/type_def.go
+++ b/go/fory/type_def.go
@@ -931,7 +931,7 @@ func (d *DynamicFieldType) String() string {
func (d *DynamicFieldType) getTypeInfo(fory *Fory) (TypeInfo, error) {
// leave empty for runtime resolution, we not know the actual type here
- return TypeInfo{Type: reflect.TypeOf((*interface{})(nil)).Elem(),
Serializer: nil}, nil
+ return TypeInfo{Type: reflect.TypeOf((*any)(nil)).Elem(), Serializer:
nil}, nil
}
func (d *DynamicFieldType) getTypeInfoWithResolver(resolver *TypeResolver)
(TypeInfo, error) {
@@ -958,8 +958,8 @@ func (d *DynamicFieldType) getTypeInfoWithResolver(resolver
*TypeResolver) (Type
}
}
- // Fallback to interface{} for unknown types
- return TypeInfo{Type: reflect.TypeOf((*interface{})(nil)).Elem(),
Serializer: nil}, nil
+ // Fallback to any for unknown types
+ return TypeInfo{Type: reflect.TypeOf((*any)(nil)).Elem(), Serializer:
nil}, nil
}
// buildFieldType builds field type from reflect.Type, handling collection,
map recursively
diff --git a/go/fory/type_def_test.go b/go/fory/type_def_test.go
index efbfd8311..aa336ce1c 100644
--- a/go/fory/type_def_test.go
+++ b/go/fory/type_def_test.go
@@ -58,7 +58,7 @@ func TestTypeDefEncodingDecoding(t *testing.T) {
tests := []struct {
name string
tagName string
- testStruct interface{}
+ testStruct any
}{
{
name: "SimpleStruct with basic fields",
diff --git a/go/fory/type_resolver.go b/go/fory/type_resolver.go
index ebef7083b..0828747cf 100644
--- a/go/fory/type_resolver.go
+++ b/go/fory/type_resolver.go
@@ -52,7 +52,7 @@ const (
)
var (
- interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
+ interfaceType = reflect.TypeOf((*any)(nil)).Elem()
stringType = reflect.TypeOf((*string)(nil)).Elem()
// Make compilation support tinygo
stringPtrType = reflect.TypeOf((*string)(nil))
@@ -68,8 +68,8 @@ var (
uintSliceType = reflect.TypeOf((*[]uint)(nil)).Elem()
float32SliceType = reflect.TypeOf((*[]float32)(nil)).Elem()
float64SliceType = reflect.TypeOf((*[]float64)(nil)).Elem()
- interfaceSliceType = reflect.TypeOf((*[]interface{})(nil)).Elem()
- interfaceMapType =
reflect.TypeOf((*map[interface{}]interface{})(nil)).Elem()
+ interfaceSliceType = reflect.TypeOf((*[]any)(nil)).Elem()
+ interfaceMapType = reflect.TypeOf((*map[any]any)(nil)).Elem()
stringStringMapType = reflect.TypeOf((*map[string]string)(nil)).Elem()
stringInt64MapType = reflect.TypeOf((*map[string]int64)(nil)).Elem()
stringIntMapType = reflect.TypeOf((*map[string]int)(nil)).Elem()
@@ -106,7 +106,7 @@ var generatedSerializerFactories = struct {
}
// RegisterSerializerFactory registers a factory function for a generated
serializer
-func RegisterSerializerFactory(type_ interface{}, factory func() Serializer) {
+func RegisterSerializerFactory(type_ any, factory func() Serializer) {
reflectType := reflect.TypeOf(type_)
if reflectType.Kind() == reflect.Ptr {
reflectType = reflectType.Elem()
@@ -317,7 +317,7 @@ func (r *TypeResolver) initialize() {
{stringType, STRING, stringSerializer{}},
{stringPtrType, STRING, ptrToStringSerializer{}},
// Register interface types first so typeIDToTypeInfo maps to
generic types
- // that can hold any element type when deserializing into
interface{}
+ // that can hold any element type when deserializing into any
{interfaceSliceType, LIST, sliceDynSerializer{}},
{interfaceMapType, MAP, mapSerializer{}},
// stringSliceType uses dedicated stringSliceSerializer for
optimized serialization
@@ -808,11 +808,6 @@ func (r *TypeResolver) getTypeInfo(value reflect.Value,
create bool) (*TypeInfo,
}
var internal = false
-
- // Early return if type registration is required but not allowed
- if !create {
- fmt.Errorf("type %v not registered and create=false",
value.Type())
- }
type_ := value.Type()
// Get package path and type name for registration
var typeName string
@@ -935,7 +930,7 @@ func (r *TypeResolver) getTypeInfo(value reflect.Value,
create bool) (*TypeInfo,
Named structs need both value and pointer types registered using the
negative ID system
to assign the correct typeID.
Multidimensional slices should use typeID = 21 for recursive
serialization; on
- deserialization, users receive []interface{} and must apply
conversion function.
+ deserialization, users receive []any and must apply conversion
function.
Array types aren’t tracked separately in fory-go’s type system;
semantically,
arrays reuse their corresponding slice serializer/deserializer. We
serialize arrays
via their slice metadata and convert back to arrays by conversion
function.
@@ -1129,7 +1124,7 @@ func (r *TypeResolver) registerType(
the serializer for typeID 23.
Overwriting here would replace info.Type with incorrect data,
causing map deserialization to load the wrong type.
- Therefore, we always keep the initial record for
map[interface{}]interface{}.
+ Therefore, we always keep the initial record for map[any]any.
For standalone maps, we use this generic type loader.
For maps inside named structs, the map serializer
will be supplied with the correct element type at
serialization time.
diff --git a/go/fory/type_test.go b/go/fory/type_test.go
index 01378b400..bbb890be5 100644
--- a/go/fory/type_test.go
+++ b/go/fory/type_test.go
@@ -39,7 +39,7 @@ func TestTypeResolver(t *testing.T) {
{reflect.TypeOf((*int)(nil)), "*int"},
{reflect.TypeOf((*[10]int)(nil)), "*[10]int"},
{reflect.TypeOf((*[10]int)(nil)).Elem(), "[10]int"},
-
{reflect.TypeOf((*[]map[string][]map[string]*interface{})(nil)).Elem(),
+ {reflect.TypeOf((*[]map[string][]map[string]*any)(nil)).Elem(),
"[]map[string][]map[string]*interface {}"},
{reflect.TypeOf((*A)(nil)), "*@example.A"},
{reflect.TypeOf((*A)(nil)).Elem(), "@example.A"},
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]