How is this pattern for declaring and initalizing slices of known length?

139 views
Skip to first unread message

nc

unread,
Jan 24, 2023, 3:01:32 PM1/24/23
to golang-nuts
Hi,

I have some sample code here: https://play.golang.com/p/H4kOGxamk0_D

I have used a pattern in the above playground snippet (twice: once in uniqueValues() and once in keys()) that declares and initializes a slice like: s := make([]T, 0, knownLength) . Then it ranges over something containing knownLength elements and assigns them to s using append. The thing I like about this pattern is that I don't need an index variable in my range loop and I can just get away with using append(). I am trying to avoid the need to extend the array underlying s when calling append and more generally to do this initialization efficiently and with a minimum of code. This is also my first bit of code using generics.

I just re-read https://go.dev/blog/slices-intro and I thought it was helpful and I believe my code is okay but I would appreciate if someone had a look at it.

I'm also wondering a couple of other questions that are less important to me right now but that I would still very much appreciate having answered:

1. Is my use of generics reasonable here?
2. Is there a pretty standard package that people use for keys, values, and unique values of a map (that I would assume makes use of generics)? Can someone point me to it if so? Non-stdlib is fine.

Thank you!

- nc

Ian Lance Taylor

unread,
Jan 24, 2023, 5:06:33 PM1/24/23
to nc, golang-nuts
On Tue, Jan 24, 2023 at 12:01 PM nc <nche...@gmail.com> wrote:
>
> I have some sample code here: https://play.golang.com/p/H4kOGxamk0_D
>
> I have used a pattern in the above playground snippet (twice: once in uniqueValues() and once in keys()) that declares and initializes a slice like: s := make([]T, 0, knownLength) . Then it ranges over something containing knownLength elements and assigns them to s using append. The thing I like about this pattern is that I don't need an index variable in my range loop and I can just get away with using append(). I am trying to avoid the need to extend the array underlying s when calling append and more generally to do this initialization efficiently and with a minimum of code. This is also my first bit of code using generics.

This technique, of make([]type, 0, len) followed by an append loop, is
a common one. Personally I always use that technique if the loop
statement is at all complicated, such as if it has any sort of if
statement. For very simple loops like the ones in your example I
might just use make([]type, len) and then assign, but using append is
also good. In my opinion.


> I'm also wondering a couple of other questions that are less important to me right now but that I would still very much appreciate having answered:
>
> 1. Is my use of generics reasonable here?

Seems fine to me. Minor syntax point: you don't have to write "T
comparable, U comparable", you can write "T, U comparable".

Ian

nc

unread,
Jan 24, 2023, 10:15:13 PM1/24/23
to golang-nuts
Thanks! This is quite helpful information. I have one small followup question: when you use make([]type, len) and assign, if you were using a range loop, that would require an index variable right? In the case of ranging over a slice or array or string you could use the range's index variable, and in the case of a map you could declare an zero index var ahead of the block and increment it at the bottom of the loop? I think this sort of indexing would be necessary in order to perform the assignment. Perhaps I am being overly pedantic and I apologize if so; I just want to be really clear.

Ian Lance Taylor

unread,
Jan 24, 2023, 11:08:09 PM1/24/23
to nc, golang-nuts
On Tue, Jan 24, 2023 at 7:15 PM nc <nche...@gmail.com> wrote:
>
> Thanks! This is quite helpful information. I have one small followup question: when you use make([]type, len) and assign, if you were using a range loop, that would require an index variable right? In the case of ranging over a slice or array or string you could use the range's index variable, and in the case of a map you could declare an zero index var ahead of the block and increment it at the bottom of the loop? I think this sort of indexing would be necessary in order to perform the assignment. Perhaps I am being overly pedantic and I apologize if so; I just want to be really clear.

That is correct.

Ian


> On Tuesday, January 24, 2023 at 6:06:33 PM UTC-4 Ian Lance Taylor wrote:
>>
>> On Tue, Jan 24, 2023 at 12:01 PM nc <nche...@gmail.com> wrote:
>> >
>> > I have some sample code here: https://play.golang.com/p/H4kOGxamk0_D
>> >
>> > I have used a pattern in the above playground snippet (twice: once in uniqueValues() and once in keys()) that declares and initializes a slice like: s := make([]T, 0, knownLength) . Then it ranges over something containing knownLength elements and assigns them to s using append. The thing I like about this pattern is that I don't need an index variable in my range loop and I can just get away with using append(). I am trying to avoid the need to extend the array underlying s when calling append and more generally to do this initialization efficiently and with a minimum of code. This is also my first bit of code using generics.
>>
>> This technique, of make([]type, 0, len) followed by an append loop, is
>> a common one. Personally I always use that technique if the loop
>> statement is at all complicated, such as if it has any sort of if
>> statement. For very simple loops like the ones in your example I
>> might just use make([]type, len) and then assign, but using append is
>> also good. In my opinion.
>>
>>
>> > I'm also wondering a couple of other questions that are less important to me right now but that I would still very much appreciate having answered:
>> >
>> > 1. Is my use of generics reasonable here?
>>
>> Seems fine to me. Minor syntax point: you don't have to write "T
>> comparable, U comparable", you can write "T, U comparable".
>>
>> Ian
>
> --
> 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/3bc68355-4993-4995-bb7c-6bd7a859dbf7n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages