개발/Go

[Go] 기초 - 인터페이스

devhooney 2022. 7. 30. 01:05
728x90

1. Go 인터페이스

- 구조체(struct)가 필드들의 집합체라면, interface는 메서드들의 집합체

- interface는 타입(type)이 구현해야 하는 메서드 원형(prototype)들을 정의

- 하나의 사용자 정의 타입이 interface를 구현하기 위해서는 단순히 그 인터페이스가 갖는 모든 메서드들을 구현하면 된다.

- 인터페이스는 struct와 마찬가지로 type 문을 사용하여 정의

type Shape interface {
    area() float64
    perimeter() float64
}

 

2. 인터페이스 구현

- 인터페이스를 구현하기 위해서는 해당 타입이 그 인터페이스의 메서드들을 모두 구현하면 되므로, 위의 Shape 인터페이스를 구현하기 위해서는 area(), perimeter() 2개의 메서드만 구현하면 된다. 

//Rect 정의
type Rect struct {
    width, height float64
}
 
//Circle 정의
type Circle struct {
    radius float64
}
 
//Rect 타입에 대한 Shape 인터페이스 구현 
func (r Rect) area() float64 {
	return r.width * r.height 
}
func (r Rect) perimeter() float64 {
     return 2 * (r.width + r.height)
}
 
//Circle 타입에 대한 Shape 인터페이스 구현 
func (c Circle) area() float64 { 
    return math.Pi * c.radius * c.radius
}
func (c Circle) perimeter() float64 { 
    return 2 * math.Pi * c.radius
}

 

728x90

3. 인터페이스 사용

- 인터페이스를 사용하는 일반적인 예로 함수가 파라미터로 인터페이스를 받아들이는 경우를 들 수 있다.

- 함수 파라미터가 interface 인 경우, 이는 어떤 타입이든 해당 인터페이스를 구현하기만 하면 모두 입력 파라미터로 사용될 수 있다는 것을 의미한다.

type Shape interface {
    area() float64
    perimeter() float64
}

//Rect 정의
type Rect struct {
    width, height float64
}
 
//Circle 정의
type Circle struct {
    radius float64
}

//Rect 타입에 대한 Shape 인터페이스 구현 
func (r Rect) area() float64 {
    return r.width * r.height 
}
func (r Rect) perimeter() float64 {
     return 2 * (r.width + r.height)
}
 
//Circle 타입에 대한 Shape 인터페이스 구현 
func (c Circle) area() float64 { 
    return math.Pi * c.radius * c.radius
}
func (c Circle) perimeter() float64 { 
    return 2 * math.Pi * c.radius
}
 
func main() {
    r := Rect{10., 20.}
    c := Circle{10}
 
    showArea(r, c)
}
 
func showArea(shapes ...Shape) {
    for _, s := range shapes {
        a := s.area() //인터페이스 메서드 호출
        println(a)
        // 200
        // 62.8
    }
}

 

4. 인터페이스 타입

- 빈 인터이스는 인터페이스 타입(interface type)이라 한다.

- 빈 인터페이스의 표현은 interface{} 이다.

func Marshal(v interface{}) ([]byte, error);
 
func Println(a ...interface{}) (n int, err error);

Empty interface는 메소드를 전혀 갖지 않는 빈 인터페이스다.

- 모든 Type을 나타내기 위해 빈 인터페이스를 사용한다.

- 빈 인터페이스는 어떠한 타입도 담을 수 있는 컨테이너

- empty interface는 Java 에서 object라 볼 수 있다.

package main
 
import "fmt"
 
func main() {
    var x interface{}
    x = 1 
    x = "Tom"
 
    printIt(x)
}
 
func printIt(v interface{}) {
    fmt.Println(v) //Tom
}

 

5. Type Assertion

Interface type의 x와 타입 T에 대하여 x.(T)로 표현했을 때, 이는 x가 nil이 아니며, x는 T 타입에 속한다는 점을 확인(assert)하는 것으로 이러한 표현을 "Type Assertion"이라 부른다.

- 만약 x가 nil 이거나 x의 타입이 T가 아니라면, 런타임 에러가 발생할 것이고, x가 T 타입인 경우는 T 타입의 x를 리턴한다. 즉, 아래 예제에서 변수 j는 a.(int)로부터 int형 변수 j가 된다.

func main() {
    var a interface{} = 1
 
    i := a       // a와 i 는 dynamic type, 값은 1
    j := a.(int) // j는 int 타입, 값은 1
 
    println(i)  // 포인터주소 출력
    println(j)  // 1 출력
}
728x90

'개발 > Go' 카테고리의 다른 글

[Go] 기초 - defer&panic  (0) 2022.08.01
[Go] 기초 - Error  (0) 2022.07.31
[Go] 기초 - 메소드  (1) 2022.07.27
[Go] 기초 - 구조체(Struct)  (0) 2022.07.27
[Go] 기초 - 패키지  (0) 2022.07.25