0

I'm working on a project. This is my first time of using generics in Go in a project. So far, for the function and the code itself, it works fine. But, I encountered a problem when I'm trying to create a unit test that uses struct for test tables.

This is the type definition & the function I wanna test.

type AllowedTypes interface {
  int | int8 | int16 | int32 | int64 | float32 | float64 | string
}

func LinearSearch[T AllowedTypes](value T, array []T){
    for _, e := range array {
        if e == value {
            return true
        }
    }

    return false
}

That code above works fine. But, when I'm trying to create the

func TestLinearSearch(t *testing.T) {
    type tableProps[T AllowedTypes] struct {
        Name           string
        Value          T
        Array          []T
        ExpectedResult bool
    }

    tables := []tableProps{
        {
            Name:           "Success: Value Exists (int)",
            Value:          5,
            Array:          []interface{}{1, 3, 5, 6, 8},
            ExpectedResult: true,
        },
        {
            Name:           "Success: Value Exists (string)",
            Value:          "y",
            Array:          []interface{}{"a", "c", "f", "g", "y"},
            ExpectedResult: true,
        },
    }

    for _, tc := range tables {
        t.Run(tt.Name, func(t *testing.T) {
            actualResult := LinearSearch(tc.Value, tc.Array)

            require.Equal(t, tc.ExpectedResult, actualResult)
        })
    }
}

The code above itself throws this error

cannot use generic type tableProps[T AllowedTypes] without instantiation

So, I assumed that I have to instantiate the generic type into the struct object. So, I changed the code to be something like this

func TestLinearSearch(t *testing.T) {
    type tableProps[T AllowedTypes] struct {
        Name           string
        Value          T
        Array          []T
        ExpectedResult bool
    }

    tables := []tableProps[AllowedTypes]{
        {
            Name:           "Success: Value Exists (int)",
            Value:          5,
            Array:          []AllowedTypes{1, 3, 5, 6, 8},
            ExpectedResult: true,
        },
        {
            Name:           "Success: Value Exists (string)",
            Value:          "y",
            Array:          []AllowedTypes{"a", "c", "f", "g", "y"},
            ExpectedResult: true,
        },
    }

    for _, tc := range tables {
        t.Run(tt.Name, func(t *testing.T) {
            actualResult := LinearSearch(tc.Value, tc.Array)

            require.Equal(t, tc.ExpectedResult, actualResult)
        })
    }
}

This one also doesn't work. But it throws a different error message:

cannot use type AllowedTypes outside a type constraint: interface contains type constraints

So, how am I supposed to use the custom generics into a slice of structs like on my case above?

I've googled the solutions but the only things I found is to tell me that I need to istantiate it using the generic type like this.

    tables := []tableProps[int]{
        {
            Name:           "Success: Value Exists (int)",
            Value:          5,
            Array:          []int{1, 3, 5, 6, 8},
            ExpectedResult: true,
        },
    }

I tried it and it works (for the first the case). But, if I use this solution, it means the data type for Value and Array field needs to be int and []int respectively which as you can see it won't be appropriate for my case because I'm gonna use lots of other data types (under AllowedTypes) for other cases simulataneously.

new line
  • 183
  • 2
  • 9
  • you can't have a slice of different instantiations of a generic type. the only way is `[]any` – blackgreen Oct 25 '22 at 19:52
  • also consider that it doesn't make a lot of sense to test the function for each possible type in its constraint. You wrote the function to be **generic**. If it compiles in the first place, it will behave the same for any type argument, as long as the operators have the same semantics (in your case `==` does) – blackgreen Oct 25 '22 at 19:54

0 Answers0