最終更新日: 2026-07-25
TOP(About this memo)) > 一覧(Go) > インターフェース
An interface type defines a type set. A variable of interface type can store a value of any type that is in the type set of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil.
type iface struct {
tab *itab
data unsafe.Pointer
}
type any = interface{}
var i interface{} = "hello"
func f(a any) {}
func main() {
f("a")
}
import "fmt"
func main() {
//f0("aaaa")
f1("aaaa")
f1(1)
f1(nil)
f1((*int)(nil))
}
func f0(a int) {
fmt.Println(a == 1)
}
func f1(a any) {// any型として受け取る
fmt.Println("---")
fmt.Println(a == 1)// anyはどの型とも比較ができる
fmt.Println(a == nil)
fmt.Println(a == (*int)(nil))
}
package main
func main() {
f1(t1("test"))
f2(t1("test"))
}
func f1(a i1) {
t := a.(t1)// interfaceは具象の情報を持つのでアサーションが可能
println(t.m2())
println(a.m())
}
func f2[U i1](a U) {
println(a.m())
}
// i1 に関する記述は不要 であることが特徴
type t1 string
func (t t1) m() string {
return string(t)
}
func (t t1) m2() string {
return string(t) + string(t)
}
// interface
type i1 interface{ m() string }
type I interface{}
type I2 interface{ M() }
type I3 interface {
M()
N()
}
func main() {
var i I
var i2 I2
var i3 I3
i = i2
i = i3
// i2 = i // annot use i (variable of type I) as I2 value in assignment: I does not implement I2 (missing method M)
i2 = i3
// i3 = i2 //cannot use i2 (variable of type I2) as I3 value in assignment: I2 does not implement I3 (missing method N)
}
package main
func main() {
f0(getErr())// こちらはOK: 実体がnilでもerror型として渡すことができる
f1(getErr())// こちらはpanic
}
func getErr() error {
// nilをerrorとして返すことができる。
return nil
}
func f0(a error) error {
return a// error型として受け取っているので、error型として返すことができる
}
func f1(a any) error {
// return a// error型ではないのでコンパイルエラー
return a.(error)// panic: any型として受け取ると、もうerror型にすることはできない。
}
package main
import (
"fmt"
"reflect"
)
type myError struct {
message string
}
func (e *myError) Error() string { // myErrorはerror interfaceを実装している。
return e.message
}
func main() {
var nilErr error
fmt.Println("is nil:", nilErr == nil) // true
fmt.Println("Type:", reflect.TypeOf(nilErr)) // <nil>
fmt.Println("Value:", reflect.ValueOf(nilErr)) // <invalid reflect.Value>
var p *myError
fmt.Println("is nil:", p == nil) //true
var notNilErr error = p
fmt.Println("is nil:", notNilErr == nil) // これは、false
fmt.Println("Type:", reflect.TypeOf(notNilErr)) // *main.myError
fmt.Println("Value:", reflect.ValueOf(notNilErr)) // myError: <nil>
}
package main
type MyInt int32
type MyStruct struct{}
type i interface{}
type MyStruct2 struct{ i }
func hoge() *MyStruct {
var a *MyStruct
return a
}
func hoge2() i {
var a *MyStruct2
return a
}
func fuga(a interface{}) {
println(a == nil)
}
func main() {
var a *int32
var b *MyInt
var c *MyStruct
var d *MyStruct2
println(a == nil) // true: 通常は比較してtrueとなる
println(b == nil) // true: 通常は比較してtrueとなる
println(c == nil) // true: 通常は比較してtrueとなる
println(d == nil) // true: 通常は比較してtrueとなる
println(hoge() == nil) // true: interface型にはなっていないので比較してtrueとなる
println(hoge2() == nil) // false: inteface型であり、型が一致しないとfalseとなる。
println(hoge2() == (*MyStruct2)(nil)) // true: inteface型であり、型が一致するのtrueとなる。
fuga(a) // false: inteface型として渡され、型が一致しないためfalseとなる。
fuga(nil) // true: inteface型として渡され、型がないためtrueとなる。
fuga((*int32)(nil)) // false: inteface型として渡され、 型が一致しないためfalseとなる。
fuga((error)(nil)) // true: errorはinterfaceだからtrueになる?
}
package main
type MyError struct{}
func (e *MyError) Error() string { return "error!" }
func hoge() error {
var myErr *MyError // この時点ではmyErr == nil
// 処理中にエラーがあればmyErrに代入することを想定。
return myErr
}
func fuge() error {
return (*MyError)(nil)
}
func main() {
println(hoge() == nil) // falseになってしまう!
println(hoge() == (*MyError)(nil)) // true
println(fuge() == nil) // falseになってしまう!
println(fuge() == (*MyError)(nil)) // true
}
if エラーを検出 {
return &MyError{}
}
// 正常終了
return nil
package main
type i interface {
M()
}
type t string
func (tt *t) M() {
}
func main() {
var ii i
// ii.M()// これは型情報の無いnilのためpanicとなる。
var tt *t
ii = tt
ii.M()// これは型情報が入っているnilのためpanicとならない。
}
i := interface{}("hello")
s := i.(string)
var x float64 = 3.4
v := reflect.ValueOf(x)
y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)
i := interface{}("hello")
n, ok := i.(int)
fmt.Println(n, ok) // 0 false
if pinger, ok := db.ConnPool.(interface{ Ping() error }); ok {
err = pinger.Ping()
}
if driverCtx, ok := driveri.(driver.DriverContext); ok {
...
}
i := interface{}("hello")
switch i.(type) {
case string:
fmt.Println("string")// string
default:
panic("")
}
func (db *DB) Select(query interface{}, args ...interface{}) (tx *DB) {
...
switch v := query.(type) {
case []string:
tx.Statement.Selects = v // この時点で vは []string型として扱える。
for _, arg := range args {
switch arg := arg.(type) {
case string:
...
case []string:
...
default:
...
}
}
...
case string:
...
}
switch vv := val.(type) {
case bool:
return GetZeroVal(vv)// これだと、vvは bool値になるが、
case int, string:
return GetZeroVal(vv)// これだと、vvは any型になる。(したがって意図した結果にならない。)
}
func GetZeroVal[R any](a R) R {
return *new(R)
}
type i interface{ f() }
type s struct{}
func (ss s) f() {}
func o(arg i) {}
func main() {
o(s{})
// o(&s{}) //なんかこれでも行けた。
}
type i interface{ f() }
type s struct{}
func (ss s) f() {}
func o(arg *i) {}
// func o[T i](arg *T) {} // これだと行ける。
func main() {
// o(&s{}) //エラー
o(new(i)) // *iを渡すと通る。
}
package main
type MyInteface interface {
Test()
}
type MyInteface2 interface {
MyInteface
}
type Usecase string
func (u Usecase) Test() {}
func main() {
F1(Usecase(""))
}
func F1(a MyInteface2) {
a.Test()
}
package main
type I interface {
Test()
Test2()
}
type S struct {
I
}
func (s S) Test2() {}
func main() {
F1(S{})
}
func F1(a I) {
//a.Test()//実装していない場合は実行時エラーとなる
a.Test2()
}
// An interface representing only the type int.
interface {
int
}
// An interface representing all types with underlying type int.
interface {
~int
}
// An interface representing all types with underlying type int that implement the String method.
interface {
~int
String() string
}
// An interface representing an empty type set: there is no type that is both an int and a string.
interface {
int
string
}
type MyInt int
interface {
~[]byte // the underlying type of []byte is itself
~MyInt // illegal: the underlying type of MyInt is not MyInt
~error // illegal: error is an interface
}
// The Float interface represents all floating-point types
// (including any named types whose underlying types are
// either float32 or float64).
type Float interface {
~float32 | ~float64
}
Basic interfacesとは、下記のようなもの。
interface {
Read([]byte) (int, error)
Write([]byte) (int, error)
Close() error
}
var x Float // illegal: Float is not a basic interface
var x interface{} = Float(nil) // illegal
type Floatish struct {
f Float // illegal
}
type HasID[T any] interface {
GetID() string
*T
}
type Pointer[T any] interface {
*T
}