Thanks for your reply, Henry! I admit that my problem seems a little bit silly without providing the contextual information. Actually I am trying to rewrite my little [validation library](https://github.com/RussellLuo/validating) by leveraging Go generics.
For the originally non-generic [Len](https://pkg.go.dev/github.com/RussellLuo/validating/v2#Len) validator factory, I have implemented two generic versions. One for a slice: ```go // LenSlice is a leaf validator factory used to create a validator, which will // succeed when the length of the slice field is between min and max. func LenSlice[T ~[]E, E any](min, max int) (mv *MessageValidator) { mv = &MessageValidator{ Message: "with an invalid length", Validator: Func(func(field *Field) Errors { v, ok := field.Value.(T) if !ok { return NewUnsupportedErrors(field, "LenSlice") } l := len(v) if l < min && l > max { return NewErrors(field.Name, ErrInvalid, mv.Message) } return nil }), } return } ``` and the other for a map: ```go // LenMap is a leaf validator factory used to create a validator, which will // succeed when the length of the map field is between min and max. func LenMap[T map[K]V, K comparable, V any](min, max int) (mv *MessageValidator) { mv = &MessageValidator{ Message: "with an invalid length", Validator: Func(func(field *Field) Errors { v, ok := field.Value.(T) if !ok { return NewUnsupportedErrors(field, "LenMap") } l := len(v) if l < min && l > max { return NewErrors(field.Name, ErrInvalid, mv.Message) } return nil }), } return } ``` As a result, we can use them as below: ```go Schema{ F("slice", []string{"foo"}): LenSlice[[]string](0, 2), F("map", map[string]int{"a": 1, "b": 2}): LenMap[map[string]int](0, 2), } ``` *Now I am wondering if I can merge the above two versions into one generic `Len`, with the help of a constraint, say, SliceOrMap*. For example: ```go func Len[T SliceOrMap](min, max int) (mv *MessageValidator) { mv = &MessageValidator{ Message: "with an invalid length", Validator: Func(func(field *Field) Errors { v, ok := field.Value.(T) if !ok { return NewUnsupportedErrors(field, "Len") } l := len(v) if l < min && l > max { return NewErrors(field.Name, ErrInvalid, mv.Message) } return nil }), } return } ``` Then we can use the same `Len` for both a slice and a map as below instead: ```go Schema{ F("slice", []string{"foo"}): Len[[]string](0, 2), F("map", map[string]int{"a": 1, "b": 2}): Len[map[string]int](0, 2), } ``` *(NOTE*: I have posted this reply earlier, but is was not displayed (maybe due to my wrong choice of "Reply to author"). Now I post it again by selecting "Reply all".) On Friday, March 18, 2022 at 3:07:17 PM UTC+8 Henry wrote: > Have you considered this? > ```go > func IsBetween(value, min, max int) bool { > return value>=min && value <=max > } > > if IsBetween(len(myMap), 10, 25) { > //do something > } > ``` > > On Friday, March 18, 2022 at 11:20:37 AM UTC+7 RussellLuo wrote: > >> Hi there, >> >> Thanks to Go generics in 1.18, I can write a generic function >> `LenBetween` for a slice: >> >> ```go >> func SliceLenBetween[T ~[]E, E any](s T, min, max int) bool { >> return len(s) >= min && len(s) <= max >> } >> ``` >> >> as well as for a map: >> >> ```go >> func MapLenBetween[T map[K]V, K comparable, V any](s T, min, max int) >> bool { >> return len(s) >= min && len(s) <= max >> } >> ``` >> >> Is there any way to write a constraint, say, SliceOrMap, to support >> either a slice or a map? >> >> With the help of SliceOrMap, then I can write a more generic version >> `LenBetween` like this: >> >> ```go >> func MapLenBetween[T SliceOrMap](s T, min, max int) bool { >> return len(s) >= min && len(s) <= max >> } >> ``` >> >> Thanks in advance! >> > -- 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/b9790ff7-50f9-4aba-ac47-f02af7493974n%40googlegroups.com.