In realtà anche in questo caso non serviva introdurre necessariamente delle generics
---
Quindi nella maggior parte dei casi se ci ritroviamo a scrivere una funzione generica con un **parametro vincolato ad un'interfaccia** forse dobbiamo porci qualche domanda
---
---
<!-- _class: chapter -->
<!-- _class: chapter -->
# Anti-Pattern 2
# Anti-Pattern (2)
Generics vs Interfacce
Generics vs Interfacce
---
---
@ -631,7 +629,7 @@ d := &bytes.Buffer{} /* (*bytes.Buffer) */
WriteOneByte(d /* (io.Writer) */, 42)
WriteOneByte(d /* (io.Writer) */, 42)
```
```
↓
<divstyle="font-size: 45px;">↓</div>
```go
```go
d := &bytes.Buffer{} /* (*bytes.Buffer) */
d := &bytes.Buffer{} /* (*bytes.Buffer) */
@ -639,7 +637,7 @@ d := &bytes.Buffer{} /* (*bytes.Buffer) */
@ -663,9 +661,13 @@ d := &bytes.Buffer{} /* (*bytes.Buffer) */
---
---
Quindi nella maggior parte dei casi se ci ritroviamo a scrivere una funzione generica con un **parametro vincolato ad un'interfaccia** forse dobbiamo porci qualche domanda
---
<!-- _class: chapter -->
<!-- _class: chapter -->
# Pattern: "PhantomData"
# Pattern: Type-safe Database
Vediamo un analogo di `PhantomData<T>` dal Rust per rendere _type-safe_ l'interfaccia di una libreria
Vediamo un analogo di `PhantomData<T>` dal Rust per rendere _type-safe_ l'interfaccia di una libreria
---
---
@ -784,15 +786,7 @@ var Users = Table[User]{
---
---
```go
Quindi possiamo anche utilizzare le **generics** per rendere **type-safe** l'interfaccia di qualcosa che inizialmente non lo era.