I think when discussing tuples one should consider the [...]any type as an alternative to []any. Arrays supports comparison, aren't boxed and are generally more tuple-like. They can be used as map keys. Of course, they're still not really type-safe. Structs solve that and also support access by name instead of by index, so they're better in general. I have to say that whenever I've used tuples (in C++ and Python) or arrays in Go (usually [2]string), I've ended up regretting it and switching to a struct/class later.
> I tried but a[i].(T) will not take T as reflect.TypeOf. I think this is typically written as switch reflect.TypeOf(a[i]).Kind(), which gives you the underlying type (e.g. int instead of MyInt). You can then use reflect.ValueOf(a[i]).Int() and the sibling functions to access the value. Doing switch a[i].(type) is also possible but that doesn't support custom types. > I would agree, except there is no == operator defined on slices, and I'm not really sure why that is. The semantics I would expect are straightforward: i.e. length is the same, and the first 'len' slice elements compare as equal, recursively if necessary. Implementing it this way would require dereferencing the internal pointer, which could cause infinite loops if the array contains a reference to itself. For example, this code panics because it runs out of stack (it's hard to tell in the playground though): https://go.dev/play/p/zyHA7khq-d8 On Saturday, August 10, 2024 at 7:35:00 PM UTC+2 lijh8 wrote: I add nested tuple (slice) support: a := []any{"abc", 123, 3.14, 100, []any{"abc", 123, 3.14, 100}} b := []any{"abc", 123, 3.14, 100, []any{"abc", 123, 3.14, 100}} c, ok := tuple2.Cmp(a, b) fmt.Println(c, ok) ``` package tuple2 import ( "cmp" "reflect" ) func Cmp(a, b []any) (int, bool) { if len(a) != len(b) { return 0, false } for i := range a { if a[i] == nil || b[i] == nil { return 0, false } if _, boolean := a[i].(bool); boolean { return 0, false } if _, boolean := b[i].(bool); boolean { return 0, false } if a, b := reflect.TypeOf(a[i]), reflect.TypeOf(b[i]); a != b { return 0, false } if a, aOk := a[i].(string); aOk { if b, bOk := b[i].(string); bOk { if c := cmp.Compare(a, b); c != 0 { return c, true } } } if a, aOk := a[i].(int); aOk { if b, bOk := b[i].(int); bOk { if c := cmp.Compare(a, b); c != 0 { return c, true } } } if a, aOk := a[i].(float64); aOk { if b, bOk := b[i].(float64); bOk { if c := cmp.Compare(a, b); c != 0 { return c, true } } } if a, aOk := a[i].([]any); aOk { if b, bOk := b[i].([]any); bOk { if c, ok := Cmp(a, b); ok && c != 0 { return c, true } else if !ok { return 0, false } } } } return 0, true } /* func main() { a := []any{"abc", 123, 3.14} b := []any{"abc", 123, 3.14} c, ok := tuple2.Cmp(a, b) fmt.Println(c, ok) } */ ``` -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3163d798-23c4-48f9-947e-00dfc60d2791n%40googlegroups.com.