3.Go言語のデータ型
前回の記事では、Go言語の関数タイプについて学びましたが、この記事では主にインターフェースタイプについて理解しています。主に次のように:
3.6インターフェース
Go言語インターフェースは、メソッドのコレクションによって表されます。データ型(またはそれに対応するポインタ型)がインターフェイスメソッドセットスーパーセットの付随するメソッドのセットである限り、その型がこのインターフェイスを実装していると判断できます。
3.6.1型表記
インターフェイスタイプの宣言は、いくつかのメソッド宣言で構成されています。メソッド宣言は、メソッド名とメソッドシグネチャで構成されます。インターフェイスタイプの宣言では、メソッド名を重複させることはできません。
インターフェイスタイプは、すべてのカスタムインターフェイスタイプの総称です。標準ライブラリコードパッケージsortのインターフェイスタイプInterfaceを例にとると、宣言は次のとおりです。
type Interface interface {
Len() int
Less(i, j int) bool
Swap(I, j int)
}
Go言語では、あるインターフェースタイプを別のインターフェースタイプに埋め込むことができます。次のインターフェイスタイプ宣言:
type Sortable interface {
sort.Interface
Sort()
}
上記のインターフェイスタイプSortableには、実際には4つのメソッド宣言、つまりLen、Less、Swap、Sortが含まれています。
Go言語は、典型的な型駆動型のサブクラス化メソッドを提供しませんが、この埋め込みメソッドを使用して同じ効果を実現します。タイプ埋め込みは、非埋め込みスタイルも具体化します。これは、以下で説明する構造タイプにも適用できます。
注:インターフェースタイプは、他のインターフェースタイプの埋め込みのみを受け入れます。
インターフェイスの埋め込みの場合、直接埋め込みや間接埋め込みなど、インターフェイス自体に埋め込むことができないという制約が1つあります。
次のように直接埋め込みます。
type Interface1 interface {
Interface1
}
間接的な埋め込みがある次のとおりです。
type Interface2 interface {
Interface3
}
type Interface3 interface {
Interface2
}
インターフェイスの埋め込みが間違っていると、コンパイルエラーが発生します。さらに、現在のインターフェイスタイプで宣言されているメソッドは、埋め込まれているインターフェイスタイプのメソッドと同じ名前にすることはできません。同じ名前を付けると、コンパイルエラーが発生します。
Go言語で定義された特別なインターフェイスタイプである空のタイプインターフェイス{}については、前述のように、メソッド宣言を含まないインターフェイスです。さらに、Go言語のすべてのデータ型はその実装です。
3.6.2値の表記
インターフェイスは実装ではなく仕様であるため、Go言語のインターフェイスタイプに対応する値の表記法はありません。ただし、インターフェイスタイプの変数には、このインターフェイスタイプを実装する任意のデータ型の値を割り当てることができるため、インターフェイスタイプの値は、このインターフェイスタイプを実装する他のデータ型の値で表すことができます。
3.6.3プロパティと基本操作
インターフェイスの最も基本的な属性は、メソッドコレクションです。
インターフェイスタイプの実装は、このデータ型にアタッチされたメソッドセットがインターフェイスタイプのメソッドセットのスーパーセットである限り、任意のカスタムデータ型にすることができます。次のように、カスタムデータ型SortableStringsを記述します。
type SortableStrings [3]string
上記のカスタムデータ型は、[3]文字列型のエイリアス型と同等です。今、あなたはこのカスタムデータ型を実装する場合sort.Interfaceのインターフェイスタイプを、あなたが実装する必要がで宣言されたすべてのメソッドsort.Interfaceを。これらのメソッドの実装は型が必要ですSortableStrings受信機の種類としては。これらのメソッドの宣言は次のとおりです。
func (self SortableStrings) Len() int {
return len(self)
}
func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
}
func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
}
上記3つの方法の宣言と、SortableStringsのタイプは、すでにの実装sort.Interfaceのインターフェイスタイプ。Go言語スタディノート2で 説明されている型アサーション式の検証を使用して、次のようにコードを記述します。
_, ok := interface{}(SortableStrings{}).(sort.Interface)
注:このステートメントをコンパイルして渡すには、最初に標準コードパッケージの並べ替えをインポートする必要があります。
上記の代入文の右側には型アサーション式があり、左側の2つの識別子はこの式の評価結果を表しています。ここでは、型変換が成功したかどうかだけを考慮して、変換の結果を考慮しません。したがって、最初の識別子は空の識別子「_」です。2番目の識別子okはブール変数を表し、trueは変換が成功したことを意味し、falseは変換が失敗したことを意味します。次の図に示すことの結果OKである真ので、SortableStringsのタイプは実装しないで宣言されたすべてのメソッドのインターフェイスタイプsort.Interfaceを。
インターフェイスタイプは、任意の数のデータタイプで実装できます。データ型は、同時に複数のインターフェイス型を実装することもできます。
上記のカスタムデータ型SortableStringsは、インターフェイス型Sortableを実装することもできます。メソッド宣言を次のように記述します。
func (self SortableStrings) Sort() {
sort.Sort(self)
}
さて、SortableStringsは実装にインターフェイスタイプを入力Sort.Interfaceをインターフェイスタイプと同時にソート可能。タイプアサーション式は次のように検証されます。
_, ok2 := interface{}(SortableStrings{}).(Sortable)
次の図に示すように、ok2の結果はtrueです。
これで、SortableStringsには、次のように、受信者タイプのSortableStringsから* SortableStringsまでのタイプSortメソッドが含まれていました。
func (self *SortableStrings) Sort() {
sort.Sort(self)
}
この関数のレシーバータイプは、SortableStringsタイプに対応するポインタータイプに変更されました。Sortメソッドは、値メソッドではなく、ポインターメソッドになりました。次のように、SortableStringsの値に対応するポインタ値のみが上記の型アサーションを渡すことができます。
_, ok3 := interface{}(&SortableStrings{}).(Sortable)
このとき、の値OK2があり、偽との値ok3がある真下図のように、:
次に、次のテストコードを追加します。
ss := SortableStrings("2", "3", "1")
ss.Sort()
fmt.Printf("Sortable strings: %v\n", ss)
上記の標準ライブラリコードパッケージfmtの使用法については、http://docscn.studygolang.com/pkg/fmtを参照してください。
テスト結果は次のとおりです。
上記の情報の[ 2、3、1]は、SortableStrings型の値の文字列表現です。上記の結果から、変数ssの値は並べ替えられていませんが、印刷前にSortメソッドが呼び出されていることがわかります。。
以下の説明を聞いてみましょう
。前述のように、valueメソッドでは、レシーバーの値への変更はメソッドの外部では見えません。ソートの方法SortableStringsのタイプは、実際にソートし、受信機の値を関数を使用してsort.Sort。sort.Sort関数は、sort.Interfaceパラメーター値の型を受け入れ、この値メソッドLen、Less、およびSwapを使用して、引数の各要素の場所を変更し、並べ替えジョブを完了します。SortableStringsのそれは実装がタイプ、すべてのメソッドがで宣言されたインタフェース型のsort.Interface、これらの方法は、これらの方法では、受信値の変化は、そのソース値に影響を与えないように、すべての値の方法ですが、唯一の変更それはちょうどソース値のコピー。
上記の問題のために、現在のソリューションは、にあるSortableStringsの方法の種類レン、より少ない、およびスワップ受信者の種類は、*に変更されSortableStrings、次の図に示すの結果を実行します。
しかし、この時点で、SortableStringsのタイプは、もはや実装インタフェース型のsort.Interface、および* SortableStringsにされた実装インターフェイスタイプのsort.Interface。上記の図のように、の値OKである偽。
次に、SortableStringsタイプの宣言を少し変更して、別の解決策を検討します。
type SortableStrings []string //去掉了方括号中的3
このとき、SortableStringsの配列型のエイリアス型は実際にはスライス型のエイリアス型に変更されますが、現在の関連メソッドをコンパイルできなくなります。主なエラーは次のとおりです。
上記の2つの主なエラーがあります。1つは組み込み関数lenのパラメーターがスライス値を指すポインター型の値にできないこと、もう1つはインデックス式がスライスを指すポインター型の値に適用できないことです。値。
これに以下の解決策をすることです変更の受信機の種類メソッドレン、あまり、スワップおよびソート*からSortableStringsバックにSortableStringsを。これは、変更されたSortableStringsがスライス型であり、スライス型が参照型であるためです。参照型の場合、値メソッドのレシーバー値への変更もソース値に反映されます。次の図は、変更された結果を示しています。
上記のインターフェイスに表示されるコードについては、クリックしてGoソースコードファイルをダウンロードし、自分で変更して、インターフェイスの使用法を体験できます。次のソースコードファイルをワークスペースのsrcディレクトリのパッケージに入れるだけです(パッケージは意味があります)。コマンドラインを入力し、ファイルディレクトリに上記のコマンドを入力します。もちろん、まず最初にGo言語を使用します。環境変数設備が整っている。
この記事はここで終了し、次の記事は未完成のGo言語データ型を継続します...