Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Generics to go-linq #112

Open
wants to merge 56 commits into
base: master
Choose a base branch
from
Open

Conversation

lonegunmanb
Copy link

@lonegunmanb lonegunmanb commented Aug 7, 2022

Hey guys, I like go-linq very much and I'd like to add generics support for this lib long ago, this weekend I've tried.

The trickiest part is how to create parameterized method since golang cannot do that, for example we cannot declare the following method:

func (QueryG[TOut]) GroupJoin[TOut, TInner, TKey, TResult any](inner QueryG[TInner],
	outerKeySelector func(TOut) TKey,
	innerKeySelector func(TInner) TKey,
	resultSelector func(outer TOut, inners []TInner) TResult) QueryG[TResult]

My way is declare some Expander type to do that. For this GroupJoin example:

func TestGroupJoinG(t *testing.T) {
	outer := []int{0, 1, 2}
	inner := []uint{1, 2, 3, 4, 5, 6, 7, 8, 9}
	want := []KeyValueG[int, []uint]{
		{0, []uint{2, 4, 6, 8}},
		{1, []uint{1, 3, 5, 7, 9}},
		{2, []uint{}},
	}

	actual := FromSliceG(outer).Expend4(To4[int, uint, int, KeyValueG[int, []uint]]()).(*Expended4[int, uint, int, KeyValueG[int, []uint]]).GroupJoin(
		FromSliceG(inner),
		func(i int) int { return i },
		func(ui uint) int { return int(ui) % 2 },
		func(outer int, inners []uint) KeyValueG[int, []uint] {
			return KeyValueG[int, []uint]{outer, inners}
		},
	).ToSlice()
	assert.Equal(t, want, actual)
}

We can declare an Expander object to capture the extended type parameters we need, then cast the type immediately, then we decalre these type extended method on these Expander type. The only potential risk point that have no protection from the compiler is this type casting, but they're so close so I think the risk is limited.

This pr is composed to learn go's generics and thanks to @ahmetb I had a lot of fun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant