モジュール 10 · レッスン 3 / 5コース内の 48/50~15 min
モジュールのレッスン (3/5)
ジェネリック (Go 1.18+)
Go 1.18 (2022 年 3 月) 以降、型パラメーター が利用可能になりました。関数と型は型に対してパラメーター化できます。これらを使用すると、コードを複製したり、PROTECTED_INLINE_4 + ランタイム型アサーションを使用したりせずに、Map、Filter、Set[T]、LinkedList[T] を作成できます。
汎用関数: 構文
Go
func Map[T, U any](s []T, f func(T) U) []U {
out := make([]U, len(s))
for i, v := range s {
out[i] = f(v)
}
return out
}
doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// doubled is []int{2, 4, 6}3 つの新しい要素:
- 名前の後の
[T, U any]: 型パラメータとその制約を宣言します。 any= 任意の型を受け入れる制約 (Go 1.18 以降のinterface{}のエイリアス)。- 推論:
Map([]int{...}, ...)を呼び出す場合、Map[int, int](...)を記述する必要はありません。コンパイラはT=int, U=intを推論します。
場合によっては、推論だけでは十分ではなく (T 引数のないコンストラクターなど)、明示的なインスタンス化が必要になります: New[*Server]()。
組み込みの制約
| 制約 | 意味 |
|---|---|
any | 任意のタイプ (== interface{})。 |
comparable | == および != の型: 数値、文字列、ブール値、ポインター、チャネル、同等の配列/構造体。 |
comparable は等価性を許可しますが、< または > は許可しません。
Go
func Index[T comparable](s []T, x T) int {
for i, v := range s {
if v == x { return i }
}
return -1
}</> の場合は、カスタム制約が必要です。
カスタム制約: 型共用体
制約は、「type element」句を含む インターフェイス です。
Go
type Ordered interface {
~int | ~int64 | ~float64 | ~string
}
func Min[T Ordered](a, b T) T {
if a < b { return a }
return b
}|= Union: リストされているタイプのいずれかを受け入れます。~int= "int またはtype X intとして定義された任意の型" (基になる型は同じ)。~を使用しない場合は、正確なintのみとなります。
制約では メソッドと型要素を混在させることもできます。
Go
type Stringable interface {
~string
Len() int
}ジェネリックタイプ
関数だけでなく、構造体やインターフェイスも型パラメータを持つことができます。
Go
type Set[T comparable] struct {
m map[T]struct{}
}
func NewSet[T comparable]() *Set[T] {
return &Set[T]{m: make(map[T]struct{})}
}
func (s *Set[T]) Add(v T) { s.m[v] = struct{}{} }
func (s *Set[T]) Has(v T) bool { _, ok := s.m[v]; return ok }
s := NewSet[string]()
s.Add("ada")メソッドは、型のパラメーターを超える型パラメーターを追加できません: func (s *Set[T]) MapTo[U any](...) コンパイルしません (意図的な設計上の制限)。
ジェネリック医薬品を使用する場合
はい:
- ロジックは、いくつかのタイプ (コレクション、アルゴリズム、
Map/Filter/Reduceなどのヘルパー) で真に 同一 です。 - 代わりの方法は、コードを複製するか、
interface{}+ 型アサーションを使用することです (型安全性が失われます)。
いいえ 次の場合:
- 1 つまたは 2 つのメソッドを備えたインターフェイスで十分であり、より読みやすくなっています (
io.Reader、fmt.Stringer)。 - 「できるから」パラメータ化しています: 単一のユースケース → その具体的なバージョンを作成します。
演習
運動#go.m10.l3.e1
試行回数: 0読み込み中…
一般的な機能の定義 Min[T Ordered](a, b T) の操作方法 <。 Il 制約は、fornito に命じられました。
エディターを読み込み中…
3 回の試行後に解決策が利用可能になります
運動#go.m10.l3.e2
試行回数: 0読み込み中…
Map[T, U any](s []T, f func(T) U) []U を実装します。新しい要素を復元します。
エディターを読み込み中…
3 回の試行後に解決策が利用可能になります
Quiz#go.m10.l3.e3
準備完了Quale 制約組み込みの同意 l'operatore == ma NON l'operatore <?
Go
func Index[T ???](s []T, x T) int { ... }