Skip to content

Commit 464a2af

Browse files
committed
Add Produce The Zero Value Of A Generic Type as a Go TIL
1 parent 8801f39 commit 464a2af

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
1010

1111
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
1212

13-
_1543 TILs and counting..._
13+
_1544 TILs and counting..._
1414

1515
---
1616

@@ -412,6 +412,7 @@ _1543 TILs and counting..._
412412
- [Not So Random](go/not-so-random.md)
413413
- [Parse A String Into Individual Fields](go/parse-a-string-into-individual-fields.md)
414414
- [Parse Flags From CLI Arguments](go/parse-flags-from-cli-arguments.md)
415+
- [Produce The Zero Value Of A Generic Type](go/produce-the-zero-value-of-a-generic-type.md)
415416
- [Redirect File To Stdin During Delve Debug](go/redirect-file-to-stdin-during-delve-debug.md)
416417
- [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md)
417418
- [Sleep For A Duration](go/sleep-for-a-duration.md)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Produce The Zero Value For A Generic Type
2+
3+
While writing a _pop_ function that would work with slices of a generic type, I
4+
ran into the issue of needing to produce a zero value of type `T` when
5+
returning early for an empty slice.
6+
7+
The way to arbitrarily get the zero value of a generic in Go is with `*new(T)`.
8+
9+
I was able to use this in my `Pop` function like so:
10+
11+
```go
12+
func Pop[T any](slice []T) (T, error) {
13+
if len(slice) == 0 {
14+
return *new(T), fmt.Errorf("cannot pop an empty slice")
15+
}
16+
17+
lastItem := slice[len(slice)-1]
18+
19+
slice = slice[:len(slice)-1]
20+
21+
return lastItem, nil
22+
}
23+
```
24+
25+
If this is happening in multiple functions and we want a more self-documenting
26+
approach, we can pull it out into a function `zero`:
27+
28+
```go
29+
func zero[T any]() T {
30+
return *new(T)
31+
}
32+
```

0 commit comments

Comments
 (0)