Go構造体   空インターフェース型

ホーム   Goチュートリアル
目次


空インターフェース型とは

空インターフェース型(empty interface)は、すべての型と互換性のある型です。

interface{} とだけ記述すると、すべての型と互換性のある型を指定したことになります。

emptyinterface1.go


package main

import "fmt"

type student struct {
	name  string
	score int
}

func main() {

	var obj interface{}
	
	obj = 100
	fmt.Println(obj)
	println(&obj)
	obj = "Hello"
	fmt.Println(obj)
	println(&obj)
	obj = 3.14
	fmt.Println(obj)
	println(&obj)
	obj = [3]string{"Kate", "Jane", "Mary"}
	fmt.Println(obj)
	println(&obj)
	obj = [ ]string{"Jack", "Bob", "John"}
	fmt.Println(obj)
	println(&obj)
	obj = map[string]int{"english":100, "science":80, "math":60}
	fmt.Println(obj)
	println(&obj)
	obj = student{name:"Jane", score:88}
	fmt.Println(obj)
	println(&obj)
}
    

実行結果


100
0xc000070ec0
Hello
0xc000070ec0
3.14
0xc000070ec0
[Kate Jane Mary]
0xc000070ec0
[Jack Bob John]
0xc000070ec0
map[english:100 math:60 science:80]
0xc000070ec0
{Jane 88}
0xc000070ec0
    

説明

すべて値が正常に表示されています。アドレスはすべて同じなので、同じ変数に代入されいることがわかります。

空インターフェース型の引数

関数の引数に空インターフェース型を指定すると、すべての型を受けとることができる関数になります。

emptyinterface2.go


package main

import "fmt"

type student struct {
	name  string
	score int
}

func show(obj interface{}) {
	fmt.Println(obj)
}

func main() {

	show(100)
	show("Hello")
	show(3.14)
	show([3]string{"Kate", "Jane", "Mary"})
	show([ ]string{"Jack", "Bob", "John"})
	show(map[string]int{"english":100, "science":80, "math":60})
	show(student{name:"Jane", score:88})
}
    

実行結果


100
Hello
3.14
[Kate Jane Mary]
[Jack Bob John]
map[english:100 math:60 science:80]
{Jane 88}
    

型アサーション

引数で受け取った空インターフェース型のもともとの型を知りたい場合には、型アサーションと型スィッチという 2 つの方法があります。

まずは、型アサーションを紹介します。 アサーション(assertion、表明 主張)

typeassertion.go


package main

import "fmt"

type student struct {
	name  string
	score int
}

func show(obj interface{}) {
	v1, ok := obj.(int)
	if ok {
		fmt.Println("int", v1)
	}
	v2, ok := obj.(string)
	if ok {
		fmt.Println("string", v2)
	}
	v3, ok := obj.(float64)
	if ok {
		fmt.Println("float64", v3)
	}
	v4, ok := obj.([3]string)
	if ok {
		fmt.Println("array", v4)
	}
	v5, ok := obj.([ ]string)
	if ok {
		fmt.Println("slice", v5)
	}
	v6, ok := obj.(map[string]int)
	if ok {
		fmt.Println("map", v6)
	}
	v7, ok := obj.(student)
	if ok {
		fmt.Println("student", v7)
	}
}

func main() {

	show(100)
	show("Hello")
	show(3.14)
	show([3]string{"Kate", "Jane", "Mary"})
	show([ ]string{"Jack", "Bob", "John"})
	show(map[string]int{"english":100, "science":80, "math":60})
	show(student{name:"Jane", score:88})
}
	

実行結果


int 100
string Hello
float64 3.14
array [Kate Jane Mary]
slice [Jack Bob John]
map map[english:100 math:60 science:80]
student {Jane 88}
	

コード説明


	v1, ok := obj.(int)
	

obj の型が int だったら、v1 にはその値が代入され、ok には true が代入されます。もし obj の型が int でなかったら v1 には何も代入されず、ok には false が代入されます。

型スィッチ

型アサーションが if 文を利用したものでしたが、型スィッチは switch 文を利用したものです。こちらの方がすっきりと記述できます。

typeswitch.go


package main

import "fmt"

type student struct {
	name  string
	score int
}

func show(obj interface{}) {
	
	switch v := obj.(type) {
	case int:
		fmt.Println("int", v)
	case string:
		fmt.Println("string", v)
	case float64:
		fmt.Println("float64", v)
	case [3]string:
		fmt.Println("array", v)
	case [ ]string:
		fmt.Println("slice", v)
	case map[string]int:
		fmt.Println("map", v)
	case student:
		fmt.Println("student", v)
	}
}

func main() {

	show(100)
	show("Hello")
	show(3.14)
	show([3]string{"Kate", "Jane", "Mary"})
	show([ ]string{"Jack", "Bob", "John"})
	show(map[string]int{"english":100, "science":80, "math":60})
	show(student{name:"Jane", score:88})
}
	

実行結果


int 100
string Hello
float64 3.14
array [Kate Jane Mary]
slice [Jack Bob John]
map map[english:100 math:60 science:80]
student {Jane 88}
	

コード説明


	switch v := obj.(type) {
	

この 1 行で、v には obj の値が代入され、switch 文には、obj の型が自動的に渡されています。


	case int:
	

実際に case 句で、型を判定できます。


12879 visits
Posted: Jul. 03, 2019
Update: Jul. 03, 2019

ホーム   Goチュートリアル   目次