mirror of
https://github.com/teivah/100-go-mistakes.git
synced 2026-06-20 16:45:56 +08:00
Social card
This commit is contained in:
parent
ab8c98b888
commit
21a6bc13c3
17 changed files with 1525 additions and 26 deletions
BIN
.cache/plugin/social/5a473f61c549ff7b37ce2f9ffbcb58de.png
Normal file
BIN
.cache/plugin/social/5a473f61c549ff7b37ce2f9ffbcb58de.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
BIN
.cache/plugin/social/d3b298a2767218b07117495d7beec56a.png
Normal file
BIN
.cache/plugin/social/d3b298a2767218b07117495d7beec56a.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
|
|
@ -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:** What’s 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, let’s imagine a constraint where we would like to restrict a type to any `int` type implementing the `String() string` method:
|
||||
What’s 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, let’s 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 doesn’t 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 doesn’t implement `String() string`.
|
||||
|
||||
Let’s also note the `constraints` package contains a set of common constraints such as `Signed` that includes all the signed integer types. Let’s ensure that a constraint doesn’t 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? Let’s 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)
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ nav:
|
|||
- external.md
|
||||
- Go Mistakes:
|
||||
- mistakes.md
|
||||
- Full Sections:
|
||||
- 9-generics.md
|
||||
- zh.md
|
||||
- ❤️ Go Jobs:
|
||||
- jobs.md
|
||||
|
|
|
|||
|
|
@ -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
1052
site/9-generics/index.html
Normal file
File diff suppressed because it is too large
Load diff
BIN
site/assets/images/social/9-generics.png
Normal file
BIN
site/assets/images/social/9-generics.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
|
|
@ -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">
|
||||
|
||||
|
|
|
|||
62
site/external/index.html
vendored
62
site/external/index.html
vendored
|
|
@ -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">
|
||||
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ What’s 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
|
|
@ -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.
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue