0Pricing
Go Academy · レッスン

制約:comparableとインターフェース

共用体制約と組み込みのcomparable

「制約:comparableとインターフェース」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。

制約とは

制約は、型引数として使用できる型を制限します。制約を指定しない場合、型パラメーターはany(空のインターフェース)になります。サポートされるのは、代入と==による比較だけです。

any制約

any(interface{}のエイリアス)は最も広い制約であり、すべての型が満たします。利用できる操作は、すべての型がサポートする操作、つまり代入とインターフェースパラメーターへの受け渡しだけです。

func Print[T any](v T) { fmt.Println(v) }

comparable制約

comparableは、==と!=をサポートする型に型パラメーターを制限します。型をマップのキーとして使う場合や、等価性を確認する場合に必要です。

func Contains[T comparable](s []T, v T) bool {
    for _, item := range s {
        if item == v { return true }
    }
    return false
}

インターフェース制約

特定のメソッドを必須にする制約として、インターフェースを使います。型パラメーターの型は、そのインターフェースのすべてのメソッドを持っていなければなりません。

type Stringer interface { String() string }

func Print[T Stringer](v T) {
    fmt.Println(v.String())
}

ユニオン制約

|による型のユニオンを使うと、具体的な型の集合に制限できます。これにより、どのインターフェースにも含まれない+などの演算子を使えるようになります。

type Number interface {
    int | int64 | float64
}

func Sum[T Number](s []T) T {
    var total T
    for _, v := range s { total += v }
    return total
}

基底型を対象に含める~T

~Tを使用すると、Tだけでなく、Tを基底型とするすべての型(たとえば、type MyInt intとして定義したカスタム型)を含めることができます。

type Integer interface { ~int | ~int64 }

type MyInt int
// MyInt satisfies Integer because its underlying type is int

golang.org/x/exp/constraints

constraintsパッケージには、共通の型制約インターフェースが用意されています。Ordered(<をサポート)、Integer、Float、Signed、Unsignedなどです。

import "golang.org/x/exp/constraints"

func Min[T constraints.Ordered](a, b T) T {
    if a < b { return a }
    return b
}

cmpパッケージ(Go 1.21)

Go 1.21では、標準ライブラリにcmp.Ordered制約とcmp.Compare/cmp.Less関数が追加され、exp/constraintsへの依存が不要になりました。

import "cmp"
func Min[T cmp.Ordered](a, b T) T { return min(a, b) }

制約の組み合わせ

制約に複数のインターフェースを埋め込むと、複数の特性を要求できます。

type Printable interface {
    comparable
    fmt.Stringer
}

制約の推論

コンパイラは引数から型パラメーターを推論します。制約が広すぎる場合(any)、推論の手がかりとして明示的な型引数が必要になることがあります。

comparableを使う場合

ジェネリック関数で値に対して==を使用したり、マップのキーとして格納したり、マップやセットの要素として使用したりする必要がある場合は、comparableを使用します。すべての型が比較可能なわけではありません(スライス、マップ、関数は比較できません)。

クイックチェック

~intのようなユニオン制約で、~接頭辞は何を意味しますか。

まとめ:制約

重要なポイント:

  • any:最も広い制約、comparable:==をサポート、interface:メソッドを要求
  • ユニオン(int|float64)により算術演算子を使用できます
  • ~TはTを基底型とする名前付き型を含めます
  • <、>、<=、>=の制約にはcmp.Ordered(Go 1.21以降)を使用します

よくある質問

「制約:comparableとインターフェース」レッスンは無料ですか?

はい。「制約:comparableとインターフェース」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。

「制約:comparableとインターフェース」で何を学びますか?

共用体制約と組み込みのcomparable ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Go Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「制約:comparableとインターフェース」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このGo Academyレッスンでコードを書いて実行できますか?

はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型パラメーターの構文
  2. 制約:comparableとインターフェース
  3. ジェネリックデータ構造
  4. 実践ジェネリクス:注意点
← Go Academyに戻る