Goプログラミング-インタフェース
抽象オブジェクトと対話する方法
メソッドにはメソッド名が必要 パラメータと戻りが違っても同名の方法はない インタフェースにメソッドを含まない実装 使用例
タイプ拡張に柔軟に対応
動物農場に子犬しかいないと仮定 いきなり猫が増えたので、新しいタイプ定義が必要 ただし既存のMakeSound関数はDogタイプのみをパラメータとして受け入れるためCatに対応できない
上記の例のSoundのような汎用メソッドインタフェースを作成します.
任意の値を許容できる関数、メソッド、変数値の作成
以下の構成の場合、BInterfaceとAInterfaceは互いにタイプを変換できる 変換成功 t:タイプ変換の結果 ok: true 変換失敗 t:コンクリートタイプのデフォルト値 ok: false
1.宣言
type DuctInterface interface {
Fly()
Walk(distance int) int
}
package main
import "fmt"
type Stringer interface {
String()
}
type Student struct {
Name string
Age int
}
func (s Student) String() {
fmt.Printf("안녕 내 이름은 %s이고 나이는 %d살이야!\n", s.Name, s.Age)
}
func main() {
student := Student{"철수", 31}
var stringer Stringer
stringer = student
stringer.String()
}
2.インタフェースを使用する理由
タイプ拡張に柔軟に対応
問題の状況
package main
import "fmt"
type Dog struct {
Name string
}
func (d Dog) Sound() {
fmt.Printf("[%s]: 멍멍\n", d.Name)
}
func MakeSound(dogs []Dog) {
for _, d := range dogs {
d.Sound()
}
}
func main() {
dogs := []Dog{}
dogs = append(dogs, Dog{"멍멍이"}, Dog{"왈왈이"})
MakeSound(dogs)
}
type Cat struct {
Name string
}
func (c Cat) Sound() {
fmt.Printf("[%s]: 야옹\n", c.Name)
}
// Dog 타입 슬라이스만 받음..
func MakeSound(dogs []Dog) {
for _, d := range dogs {
d.Sound()
}
}
ソリューション
上記の例のSoundのような汎用メソッドインタフェースを作成します.
package main
import "fmt"
type Animal interface {
Sound()
}
type Dog struct {
Name string
}
func (d Dog) Sound() {
fmt.Printf("[%s]: 멍멍\n", d.Name)
}
type Cat struct {
Name string
}
func (c Cat) Sound() {
fmt.Printf("[%s]: 야옹\n", c.Name)
}
func MakeSound(animals []Animal) {
for _, a := range animals {
a.Sound()
}
}
func main() {
animals := []Animal{}
animals = append(animals, Dog{"멍멍이"}, Dog{"왈왈이"}, Cat{"야옹이"})
MakeSound(animals)
}
3.インタフェース機能の詳細
3.1インタフェースを含むインタフェース
type A interface {
AA() (int, error)
CC() error
}
type B interface {
BB() (int, error)
CC() error
}
type C interface {
A
B
}
CC() error
重なっていますが、同じ方法であるため問題ありません3.2パラメータとしてインタフェース{}を受信する空のインタフェース
任意の値を許容できる関数、メソッド、変数値の作成
package main
import (
"fmt"
)
func TypeChecker(v interface{}) {
switch t := v.(type) {
case int:
fmt.Printf("v is int %d\n", v)
case string:
fmt.Printf("v is string %s\n", v)
case float64:
fmt.Printf("v is float64 %f\n", v)
default:
fmt.Printf("%T:%v type is not acceptable\n", t, t)
}
}
type Person struct {
Name string
}
func main() {
TypeChecker(32)
TypeChecker(0.5)
TypeChecker("hello")
TypeChecker(Person{"철수"})
}
4.変換インタフェース
4.1インタフェースを特定のタイプに変換
package main
import (
"fmt"
)
type AInterface interface {
DoSomething()
}
type AStruct struct {
Name string
}
func (a AStruct) DoSomething() {
fmt.Println("hello")
}
type BStruct struct {
Name string
Age int
}
func (b BStruct) DoSomething() {
fmt.Println("hello")
}
func TypeConversion(aInterface AInterface) {
b := aInterface.(*BStruct)
fmt.Println(b)
}
func main() {
a := &BStruct{"철수", 31}
TypeConversion(a) // 타입 변환 성공
b := &AStruct{"철수"}
TypeConversion(b)
// > b가 가리키는 타입은 *AStruct이지만 *BStruct로 타입 변환하려고 했기 때문에 런타임 에러 발생
}
4.2タイプを別のインタフェースに変換
package main
import (
"fmt"
)
type AInterface interface {
DoSomething()
}
type BInterface interface {
DoNothing()
}
type AStruct struct {
Name string
}
func (a AStruct) DoSomething() {
fmt.Println("hello")
}
func (a AStruct) DoNothing() {
fmt.Println("hello")
}
func TypeConversion(bInterface BInterface) {
a := bInterface.(AInterface)
fmt.Println(a)
}
func main() {
a := &AStruct{"철수"}
TypeConversion(a)
}
4.3インタフェースの変換時の異常処理方法
var a Interface
if t, ok := a.(ConcreteType); ok {
...
}
Reference
この問題について(Goプログラミング-インタフェース), 我々は、より多くの情報をここで見つけました https://velog.io/@lesimor/Go-프로그래밍-인터페이스テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol