Social card

This commit is contained in:
teivah 2023-09-14 17:52:39 +01:00
parent ab8c98b888
commit 21a6bc13c3
17 changed files with 1525 additions and 26 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -1,4 +1,8 @@
# Being confused about when to use generics (#9)
---
title: Being confused about when to use generics (#9)
---
# Being confused about when to use generics
Generics is a fresh addition to the language. In a nutshell, it allows writing code with types that can be specified later and instantiated when needed. However, it can be pretty easy to be confused about when to use generics and when not to. Throughout this post, we will describe the concept of generics in Go and then delve into common use and misuses.
@ -112,33 +116,32 @@ Note that Go can infer that `getKeys` is called with a `string` type argument. T
keys := getKeys[string](m)
```
---
**NOTE:** Whats the difference between a constraint using `~int` or `int`? Using `int` restricts it to that type, whereas `~int` restricts all the types whose underlying type is an `int`.
???+ note
To illustrate it, lets imagine a constraint where we would like to restrict a type to any `int` type implementing the `String() string` method:
Whats the difference between a constraint using `~int` or `int`? Using `int` restricts it to that type, whereas `~int` restricts all the types whose underlying type is an `int`.
```go
type customConstraint interface {
~int
String() string
}
```
To illustrate it, lets imagine a constraint where we would like to restrict a type to any `int` type implementing the `String() string` method:
Using this constraint will restrict type arguments to custom types like this one:
```go
type customConstraint interface {
~int
String() string
}
```
```cgo
type customInt int
Using this constraint will restrict type arguments to custom types like this one:
func (i customInt) String() string {
return strconv.Itoa(int(i))
}
```
```go
type customInt int
As `customInt` is an `int` and implements the `String() string` method, the `customInt` type satisfies the constraint defined.
func (i customInt) String() string {
return strconv.Itoa(int(i))
}
```
However, if we change the constraint to contain an `int` instead of an `~int`, using `customInt` would lead to a compilation error because the `int` type doesnt implement `String() string`.
As `customInt` is an `int` and implements the `String() string` method, the `customInt` type satisfies the constraint defined.
---
However, if we change the constraint to contain an `int` instead of an `~int`, using `customInt` would lead to a compilation error because the `int` type doesnt implement `String() string`.
Lets also note the `constraints` package contains a set of common constraints such as `Signed` that includes all the signed integer types. Lets ensure that a constraint doesnt already exist in this package before creating a new one.
@ -146,7 +149,7 @@ So far, we have discussed examples using generics for functions. However, we can
For example, we will create a linked list containing values of any type. Meanwhile, we will write an `Add` method to append a node:
```cgo
```go
type Node[T any] struct { // Use type parameter
Val T
next *Node[T]
@ -180,7 +183,7 @@ So when are generics useful? Lets discuss a couple of common uses where gener
* Data structures. For example, we can use generics to factor out the element type if we implement a binary tree, a linked list, or a heap.
* Functions working with slices, maps, and channels of any type. For example, a function to merge two channels would work with any channel type. Hence, we could use type parameters to factor out the channel type:
```cgo
```go
func merge[T any](ch1, ch2 <-chan T) <-chan T {
// ...
}
@ -203,7 +206,7 @@ Conversely, when is it recommended **not** to use generics?
* When just calling a method of the type argument. For example, consider a function that receives an `io.Writer` and call the `Write` method:
```cgo
```go
func foo[T io.Writer](w T) {
b := getBytes()
_, _ = w.Write(b)

View file

@ -167,6 +167,8 @@ The `any` type can be helpful if there is a genuine need for accepting or return
Relying on generics and type parameters can prevent writing boilerplate code to factor out elements or behaviors. However, do not use type parameters prematurely, but only when you see a concrete need for them. Otherwise, they introduce unnecessary abstractions and complexity.
Read the full section [here](9-generics.md).
<!-- TODO Include 9-generics.md file -->
[Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go)

View file

@ -57,6 +57,8 @@ nav:
- external.md
- Go Mistakes:
- mistakes.md
- Full Sections:
- 9-generics.md
- zh.md
- ❤️ Go Jobs:
- jobs.md

View file

@ -499,6 +499,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="/9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="/zh/" class="md-nav__link">

1052
site/9-generics/index.html Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -663,6 +663,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../zh/" class="md-nav__link">

View file

@ -608,6 +608,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../zh/" class="md-nav__link">

View file

@ -606,6 +606,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="zh/" class="md-nav__link">

View file

@ -538,6 +538,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../zh/" class="md-nav__link">

View file

@ -14,7 +14,7 @@
<link rel="prev" href="../external/">
<link rel="next" href="../zh/">
<link rel="next" href="../9-generics/">
<link rel="icon" href="../img/Go-Logo_LightBlue.svg">
@ -1450,6 +1450,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../zh/" class="md-nav__link">
@ -2570,6 +2632,7 @@ Whats the main problem if we overuse interfaces? The answer is that they make
<summary>TL;DR</summary>
<p>Relying on generics and type parameters can prevent writing boilerplate code to factor out elements or behaviors. However, do not use type parameters prematurely, but only when you see a concrete need for them. Otherwise, they introduce unnecessary abstractions and complexity.</p>
</details>
<p>Read the full section <a href="../9-generics/">here</a>.</p>
<!-- TODO Include 9-generics.md file -->
<p><a href="https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go">Source code</a></p>

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,11 @@
<lastmod>2023-09-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://100go.co/9-generics/</loc>
<lastmod>2023-09-14</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://100go.co/chapter-1/</loc>
<lastmod>2023-09-14</lastmod>

Binary file not shown.

View file

@ -11,7 +11,7 @@
<link rel="canonical" href="https://100go.co/zh/">
<link rel="prev" href="../mistakes/">
<link rel="prev" href="../9-generics/">
<link rel="next" href="../jobs/">
@ -539,6 +539,68 @@
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_2" >
<label class="md-nav__link" for="__nav_2_2" id="__nav_2_2_label" tabindex="0">
<span class="md-ellipsis">
Full Sections
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2_2">
<span class="md-nav__icon md-icon"></span>
Full Sections
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../9-generics/" class="md-nav__link">
<span class="md-ellipsis">
Being confused about when to use generics (#9)
</span>
</a>
</li>
</ul>
</nav>
</li>