インターフェース、インターフェース{}、変換
Goのインターフェースはメソッドセット。このメソッドセットを実装するタイプは、次のように言われます。インターフェイスを実装する。
インターフェイスは暗黙的に実装されます。ありません実装キーワード、他の言語で使用されます。タイプがインターフェイスのメソッドセット全体を定義する場合、それを実装します。これは構造型と呼ばれ、コンパイル時の同等物です。ダックタイピング。
アヒルのように歩き、アヒルのように泳ぎ、アヒルのように鳴くなら、それはアヒルです
重要:Goでは、インターフェースはデータではなく一連のメソッド(アクション)を抽象化します。
例
次の例はGoでインターフェースを使用する方法は、話すことができる動物の基本的なインターフェイスと、インターフェイスを満たすさまざまな構造体を示しています。
type Animal interface {
Speak() string
}
type Dog struct {
}
func (d Dog) Speak() string {
return “Woof!”
}
type Cat struct {
}
func (c Cat) Speak() string {
return “Meow!”
}
type Llama struct {
}
func (l Llama) Speak() string {
return “???”
}
type JavaProgrammer struct {
}
func (j JavaProgrammer) Speak() string {
return “Design patterns!”
}
[]動物を作成して実行できますSpeak()
その内容について:
func main() {
animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}
空のインターフェース
ザ・Animal
インターフェースは小さくて素敵ですが、初心者にはもっと単純で、それでもやや複雑な概念があります。それは空のインターフェースです。
interface{}
重要な概念であるGoemptyインターフェースです。すべてのタイプは、定義によりそれを実装します。
インターフェイスはタイプであるため、次のように定義できます。
type Dog struct {
Age interface{}
}
また、空のインターフェイスタイプを関数パラメータとして渡すこともできます。
func Eat(t interface{}) {
// ...
}
受け入れるinterface{}
関数が任意の型を受け入れることを意味するのではなく、Eatが次の値を受け入れることを意味します。interface{}
タイプ。
実行時に、Goは渡された実際の値をに変換しますinterface{}
値。
タイプを使用して構造体のフィールドを定義する場合interface{}
、任意のタイプの値を割り当てることができます。例えば:
package main
import “fmt”
type Dog struct {
Age interface{}
}
func main() {
dog := Dog{}
dog.Age = “3”
fmt.Printf("%#v %T\n", dog.Age, dog.Age)
<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span> = <span style="color:#ae81ff">3</span>
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%#v %T\n"</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>)
<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span> = <span style="color:#e6db74">"not really an age"</span>
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%#v %T"</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>)
}
プリント
"3" string
3 int
"not really an age" string
もちろん、これは基本的なタイプに限定されません。スライス、マップ、カスタム構造体をそこに格納できます。
インターフェイスが内部でどのように表されるか
内部的には、インターフェース値2つですwords
、バイトのセット。
1つの単語は、型の基礎となる値を指します。一言でデータを指します。
変換
やったときanimals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
以前は、Goはすべての特定の動物タイプを自動的に動物タイプに変換していました。そのスライスのすべての要素は現在、タイプAnimalであり、基になるタイプは、Dog、Cat、Llamaなどの特定の種を指しています。
しかし、メソッドが受け入れる場合[]interface{}
たとえば、私たちはただ渡すことはできませんanimals
タイプが一致しないため、それに。必要があるそれぞれを明示的に変換するAnimal
にinterface{}
前に、ループで、[] Tを[]インターフェース{}に変換できますかよくある質問:
t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
s[i] = v
}
の基になるタイプを決定しますinterface{}
値がタイプの場合interface{}
、基になる型を判別することをお勧めします。どうやって?スイッチをオンにした状態.(type)
、 お気に入り効果的な囲碁説明:
スイッチを使用して、インターフェイス変数の動的タイプを検出することもできます。このようなタイプスイッチは、括弧内にキーワードタイプを含むタイプアサーションの構文を使用します。スイッチが式で変数を宣言する場合、変数は各句で対応するタイプになります。このような場合に名前を再利用することも慣用的であり、事実上、同じ名前であるがそれぞれの場合で異なる型の新しい変数を宣言します。
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
その他のチュートリアル:
- NGINXリバースプロキシを使用してGoサービスを提供する
- Goで構造体のコピーを作成する
- GoWebサーバーの基本
- Goでのマップタイプの並べ替え
- 一言で言えばポインタを移動します
- タグの説明に行く
- 日付と時刻のフォーマットに移動
- Goを使用したJSON処理
- 可変個引数関数に移動
- GoStringsチートシート
- GoEmptyインターフェイスの説明
- Go withVSCodeとDelveのデバッグ
- NamedGoはパラメータを返します
- Goで乱数と文字列を生成する
- Goプロジェクトのファイルシステム構造
- Goに実装された二分探索アルゴリズム
- Goでのコマンドラインフラグの使用
- GOPATHの説明
- Goでコマンドラインアプリを作成する:lolcat
- Goを使用したCLIコマンドの作成:cowsay
- Goでのシェルパイプの使用
- CLIチュートリアルに移動:フォーチュンクローン
- Goを使用してフォルダ内のファイルを一覧表示します
- Goを使用して、GitHubからリポジトリのリストを取得します
- 移動し、文字列のスライスをファイルに追加します
- 文字列をバイトスライスに変換します
- GoでローカルGitの貢献を視覚化する
- GoCPUとメモリプロファイリングの開始
- Goプログラムの「インデックス作成をサポートしていません」エラーを解決する
- Goプログラムでの実行時間の測定
- 重複するタイトルを検出するためにGoを使用してWebクローラーを構築する
- ベストプラクティスに進む:ポインターまたは値のレシーバー?
- ベストプラクティスに進む:メソッドまたは関数を使用する必要がありますか?
- データ構造の移動:設定
- マップのチートシートに移動
- Goでジェネリック型の実装を生成する
- Goデータ構造:辞書
- Goデータ構造:ハッシュテーブル
- Go throughChannelsにイベントリスナーを実装する
- Goデータ構造:スタック
- データ構造の移動:キュー
- Goデータ構造:二分探索木
- Goデータ構造:グラフ
- Goデータ構造:リンクリスト
- Goデータ構造の完全ガイド
- Go値の比較
- Goはオブジェクト指向ですか?
- GoでのSQLデータベースの操作
- Goでの環境変数の使用
- チュートリアルに進む:PostgreSQLに裏打ちされたREST API
- GoWebサーバーでのCORSの有効化
- DockerコンテナへのGoアプリケーションのデプロイ
- GoがPHP開発者として学ぶための強力な言語である理由
- 移動し、io.Reader.ReadString改行文字を削除します
- 移動、変更を監視してプログラムを再構築する方法
- 行って、日付からの月を数えます
- GoでHTTPPOSTパラメーターにアクセスする