_interface_typ_
은 메소드의 시그니처 집합으로 구성된다.
- 인터페이스 유형의 값은 해당 메소드를 구현하는 모든 값을 보유 할 수 있다.
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f // a MyFloat implements Abser
fmt.Println(a.Abs())
a = &v // a *Vertex implements Abser
fmt.Println(a.Abs())
// In the following line, v is a Vertex (not *Vertex)
// and does NOT implement Abser.
a = v
fmt.Println(a.Abs()) // error
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
인터페이스의 암시적 구현
type implements
는 메소드를 실행함으로써 인터페이스를 구현한다. 키워드는 필요없다.
- 암시적 인터페이스는 인터페이스의 정의를 구현으로부터 분리하며, 이는 사전 정렬 없이 어떠한 패키지에 등장할 수 있다.
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M() {
fmt.Println(t.S)
}
func main() {
var i I = T{"hello"}
i.M()
}
인터페이스 값
- 인터페이스는 기본적으로
(value, type)
타입의 튜플이라 생각할 수 있다.
- 인터페이스 값으로 메서드를 호출하면 동일한 이름의 구현된 메서드를 호출한다.
package main
import (
"fmt"
"math"
)
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
fmt.Println(t.S)
}
type F float64
func (f F) M() {
fmt.Println(f)
}
func main() {
var i I
i = &T{"Hello"}
describe(i)
i.M() // T.M() 이 실행됨
i = F(math.Pi)
describe(i)
i.M() // F.M() 이 실행됨
}
func describe(i I) {
fmt.Printf("(%v, %T)\\n", i, i)
}
Nil 인터페이스 값
- 인터페이스 자체 내부의 콘크리트 값이 0일 경우 (할당된 값이 없는 경우) 메소드 호출시 nil 리시버로 호출된다.
- 일반적인 언어에서는 null 포인터 예외를 발생시키지만, Go 에서는 nil 리시버로 호출된다.
- nil 콘크리트 값을 갖는 인터페이스 값 자체가 nil이 아니라는 점에 유의해야 합니다.
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
if t == nil {
fmt.Println("<nil>")
return
}
fmt.Println(t.S)
}
func main() {
var i I
var t *T // 정의된 값이 없음
i = t
describe(i)
i.M() // nil
i = &T{"hello"}
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("(%v, %T)\\n", i, i)
}