Thanks for your help and very interesting ideas. In the end I used this: type Set[T comparable] map[T]struct{}
func New[T comparable](elements ...T) Set[T] { set := make(Set[T], len(elements)) for _, element := range elements { set[element] = struct{}{} } return set } func (me Set[T]) String() string { elements := make([]T, 0, len(me)) for element := range me { elements = append(elements, element) } sort.Slice(elements, func(i, j int) bool { return less(elements[i], elements[j]) }) s := "{" sep := "" for _, element := range elements { s += sep + asStr(element) sep = " " } return s + "}" } func asStr(x any) string { if s, ok := x.(string); ok { return fmt.Sprintf("%q", s) } return fmt.Sprintf("%v", x) } func less(a, b any) bool { switch x := a.(type) { case int: return x < b.(int) case float64: return x < b.(float64) case string: return x < b.(string) default: return fmt.Sprintf("%v", a) < fmt.Sprintf("%v", b) } } Interestingly, I couldn't put the asStr() code in the String() function since doing so produced this error: invalid operation: cannot use type assertion on type parameter value element (variable of type T constrained by comparable) Anyway, I'm happy that it all works now. (I know I ought to include every int & float32, but this is enough for now). On Tuesday, November 8, 2022 at 11:29:34 AM UTC rog wrote: > If you're sure that T is an int or a string, then why not constrain it as > such? https://go.dev/play/p/1kT6EacMHco > > You could go further and constrain it to allow any type with ordering > defined: https://go.dev/play/p/il5koj1RPkh > > If you want to allow any kind of comparable key in your set, one could > observe that essentially you're trying to solve the same problem that the > fmt package is solving when it converts maps to string. It uses the > internal fmtsort <https://pkg.go.dev/internal/fmtsort> package, which, as > luck would have it, has been factored out into an externally available > package <https://pkg.go.dev/github.com/rogpeppe/go-internal/fmtsort>. So > you could do this: https://go.dev/play/p/oKTGSm_o22a > > To answer the specific question you asked, there is an issue that tracks > the ability to do a switch directly on a type parameter: > https://github.com/golang/go/issues/45380 > > But you can also work around the lack of that feature by doing something > like this: https://go.dev/play/p/3C2a61Ojbxs > > Hope this helps, > > rog. > > > On Tue, 8 Nov 2022 at 08:53, 'Mark' via golang-nuts < > golan...@googlegroups.com> wrote: > >> Given a function: >> >> func F[T comparable](a T) { >> } >> >> is it possible to check T's type inside F? >> >> My use case is that I have a function with signature G[T comparable](x >> []T) and inside G I want to sort the elements in slice x where T could be >> int or string. >> >> This arises in a tiny generic set module I've created: >> https://github.com/mark-summerfield/gset >> In the String() method I want to return a string with the elements sorted >> (for human readability and for testing convenience); but at the moment I >> can only do this by converting all elements to strings and sorting them >> which isn't good for ints. >> >> -- >> 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...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/e746f065-24fa-474a-90ec-2d8367bf3e3bn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/e746f065-24fa-474a-90ec-2d8367bf3e3bn%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- 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/dea0057c-fd75-4a05-a171-0a77bbd1d051n%40googlegroups.com.