Go 言語はインターフェースを開発できます。 Go 言語のインターフェイスは、一連のメソッドのシグネチャです。これは Go 言語の重要な部分です。インターフェイスの機能は、仕様またはプロトコルの定義に似ています。各実装者は、プロトコルに従ってインターフェイスを実装するだけで済みます。 go 言語では、interface キーワードを使用してインターフェイスを定義します。構文は「type インターフェイス 型名 インターフェイス{メソッド名 1 (パラメータリスト 1) 戻り値リスト 1 メソッド名 2 (パラメータリスト 2) 戻り値リスト 2.. .}"。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
インターフェースは私たちにとってよく知られた概念です。さまざまな開発言語で広く使用されています。Java に精通している私たちのようなプログラマにとって、インターフェースはより馴染みのあるものです。以下では、インターフェースがどのようなものであるかを見てみましょうGo 言語で使用される言語と、日常の開発でそれらが果たす役割について説明します。
Go 言語のインターフェイスは、一連のメソッドのシグネチャです。これは Go 言語の重要な部分です。インターフェイスの機能は次のとおりです。仕様または合意を定義する場合、各実装当事者は合意に従ってそれを実装するだけで済みます。
インターフェイスは型です
インターフェイス型は、他の型の動作を抽象化および一般化したものです。特定の実装の詳細は考慮されません。この抽象メソッドにより、関数がより柔軟になります。
type 接口类型名 interface{ 方法名1( 参数列表1 ) 返回值列表1 方法名2( 参数列表2 ) 返回值列表2 … }
Go 言語では、interface キーワードを使用してインターフェースを定義します。
任意の型 T のメソッド セットがインターフェイス型のメソッド セットのスーパーセットである場合、型 T がそのインターフェイスを実装すると言います。 。
インターフェイスの実装は Go 言語では暗黙的であるため、2 つの型間の実装関係をコードに反映する必要はありません。Java のimplements に似たキーワードはありません。 Go 言語: Go コンパイラーは、必要に応じて 2 つの型間の実装関係を自動的にチェックします。インターフェイスを定義したら、呼び出し元がインターフェイスを正しくコンパイルして使用できるように、インターフェイスを実装する必要があります。
インターフェイスの実装は、インターフェイスを利用可能にするために 2 つのルールに従う必要があります:
1. インターフェイスのメソッドは、インターフェイスを実装する type メソッドと同じ形式です。型のインターフェイス シグネチャと一致するメソッドを追加し、このメソッドを実装します。署名には、メソッドの名前、パラメータ リスト、および戻りパラメータ リストが含まれます。つまり、実装されたインターフェイス タイプのメソッドの名前、パラメータ リスト、および戻りパラメータ リストのいずれかの項目が、インターフェイスによって実装されるメソッドと矛盾している限り、インターフェイスのこのメソッドは実装されません。 。
package main import "fmt" type Phone interface { Call() SendMessage() } type HuaWei struct { Name string Price float64 } func (h *HuaWei) Call() { fmt.Printf("%s:可以打电话",h.Name) } func (h *HuaWei) SendMessage() { fmt.Printf("%s:可以发送短信",h.Name) } func main() { h := new(HuaWei) h.Name="华为" var phone Phone phone = h phone.SendMessage() }
型がインターフェイスを実装できない場合、コンパイラはエラーを報告します:
a. 一貫性のない関数名によって引き起こされるエラー
b. 一貫性のないメソッド シグネチャによって引き起こされるエラー関数を実装するには
2. インターフェイス内のすべてのメソッドが実装されます。インターフェイスに複数のメソッドがある場合、これらのメソッドが実装されている場合にのみ、インターフェイスをコンパイルして正しく使用できます
func (h *Xiaomi) Call() { fmt.Printf("%s:可以打电话",h.Name) } func main() { h := new(Xiaomi) h.Name="小米" var phone Phone phone = h phone.SendMessage() }
Xiaomi タイプがインターフェイスに 1 つのメソッドのみを実装している場合、それを使用するとコンパイル エラーが報告されます。
型は複数のインターフェースを実装します
型は複数のインターフェースを実装できますが、インターフェースは互いに独立しており、実装はわかりません。お互いの。
たとえば、犬は移動して呼び出すことができます
package main import "fmt" type Move interface { move() } type Say interface { say() } type Dog struct { Name string } func (d *Dog) move() { fmt.Printf("%s会动\n", d.Name) } func (d *Dog) say() { fmt.Printf("%s会叫汪汪汪\n", d.Name) } func main() { var m Move var s Say d:=&Dog{ Name: "旺财", } m = d s=d m.move() s.say() }
複数の型が同じインターフェイスを実装します
Go 言語では異なる型でも同じインターフェイスを実装できます。最初に、move メソッドを必要とする Mover インターフェイスを定義します。
type Mover interface { move() }
たとえば、犬も移動でき、車も移動できます。この関係を実現するには、次のコードを使用できます:
type dog struct { name string } type car struct { brand string } // dog类型实现Mover接口 func (d dog) move() { fmt.Printf("%s会跑\n", d.name) } // car类型实现Mover接口 func (c car) move() { fmt.Printf("%s速度70迈\n", c.brand) }
現時点では、犬と車を 1 つとして扱うことができます。コード内のオブジェクトの移動 これに対処するには、オブジェクトが何であるかに注意を払う必要はなくなり、move メソッドを呼び出すだけで済みます。
func main() { var x Mover var a = dog{name: "旺财"} var b = car{brand: "保时捷"} x = a x.move() x = b x.move() }
空のインターフェイス: インターフェイス{}にはメソッドが含まれていません。このため、どの型でも空のインターフェイスが実装されるため、空のインターフェイスはあらゆる種類のデータを保存できます。
fmt
パッケージ内の Print
一連の関数。パラメータのほとんどは空のインターフェイス型で、任意の型をサポートしているとも言えます
func Print(a ...interface{}) (n int, err error) func Println(format string, a ...interface{}) (n int, err error) func Println(a ...interface{}) (n int, err error)
空のインターフェースはマップの値として使用されます
// 空接口作为map值 var studentInfo = make(map[string]interface{}) studentInfo["name"] = "李白" studentInfo["age"] = 18 studentInfo["married"] = false fmt.Println(studentInfo)
空のインターフェースはあらゆるタイプの値を格納できます。保存される特定のデータ?
インターフェイス値
インターフェイスの値 (インターフェイス値と呼ばれる) は、特定の型とその特定の型の値で構成されます。
これら 2 つの部分は、それぞれインターフェイスの動的タイプおよび動的値と呼ばれます。
空のインターフェイスの値を判定したい場合は、型アサーションを使用できます。その構文形式は次のとおりです:
x.(T)
そのうちの:
x: インターフェイス型の変数を意味します。{}
T: アサーション x の型を表します。
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。
func main() { var x interface{} x = "ms的go教程" v, ok := x.(string) if ok { fmt.Println(v) } else { fmt.Println("类型断言失败") } }
上面的示例中如果要断言多次就需要写多个if判断,这个时候我们可以使用switch语句来实现:
func justifyType(x interface{}) { switch v := x.(type) { case string: fmt.Printf("x is a string,value is %v\n", v) case int: fmt.Printf("x is a int is %v\n", v) case bool: fmt.Printf("x is a bool is %v\n", v) default: fmt.Println("unsupport type!") } }
因为空接口可以存储任意类型值的特点,所以空接口在Go语言中的使用十分广泛。
关于接口需要注意的是,只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。
以上がGo言語でインターフェースを開発できるのか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。