관리 메뉴

A seeker after truth

<할 일 목록> 웹앱 작성해보기(3) - 인터페이스(작성하다 양이 너무 많아 포기) 본문

Programming Language/Golang(Go)

<할 일 목록> 웹앱 작성해보기(3) - 인터페이스(작성하다 양이 너무 많아 포기)

dr.meteor 2019. 10. 16. 15:54

*본문은 <Go 디스커버리>(염재현 저, 한빛미디어 2016)의 5장, 6장을 공부한 뒤 정리한 내용입니다.

 

구조체는 자료들의 묶음, 인터페이스는 메서드들의 묶음. 즉, 인터페이스는 의미상으론 "무언가를 할 수 있는 것"을 의미함.

인터페이스의 대표적인 예가 io.Reader, io.Writer(입출력 인터~). io.Reader는 Read 메서드를 정의하는 자료형들을 받을 수 있다(Read 메서드가 io.Reader 인터페이스 안에 속한 메서드 중 하나여서. 근데 "메서드를 정의하는 '자료형'"...? 이 부분이 무슨 소리인지 모르겠음). 그 예로 File은 Read 메서드가 있으므로 io.Reader가 될 수 있다. 의미상으론 '읽을 수 있는 것'을 말한다.

 

인터페이스 이름을 붙일 땐 주로 인터페이스의 메서드 이름에 er을 붙인다. 예를 들어 io.Reader는 Read 메서드를 가진 인터페이스다. 문자열로 표현할 수 있는 것들은 fmt.Stringer가 된다. 내가 이름 붙인 자료형에 String 메서드만 만들어주면 문자열로 표현할 수 있는 것이 되고, fmt.Print와 같은 함수에서 이 메서드를 사용하게 된다. 손수 출력 형식을 정해줄 수 있게 된다.

* 참고

출처: https://golang.org/pkg/fmt/#Stringer

Stringer is implemented by any value that has a String method, which defines the “native” format for that value. The String method is used to print values passed as an operand to any format that accepts a string or to an unformatted printer such as Print.

type Stringer interface {
    String() string
}

이 웹앱에서의 경우 아래와 같은 방식으로 String 함수를 정의해줄 수 있다.

func (t Task) String() string {
	check := "v"
	if t.Status != DONE {
		check = " "
	}
	return fmt.Sprint("[%s] %s %s", check, t.Title, t.Deadline)
}

Stringer를 받는 프린트 함수도 작성할 수 있다.

func PrintStringer(data fmt.Stringer) {
	fmt.Print(data.String())
}

(인터페이스를 통해 저 함수를 호출하네 흐으음...)

fmt.Println(t)와 같이 평범한 함수에서 Task의 구조체를 호출하더라도 위에서 지정한대로 출력된다. fmt.Println(t) 함수가 인터페이스를 검사해서 Stringer인 경우에는 String 메서드를 호출하기 때문이다.

 

 

출처: https://golang.org/pkg/io/#Reader

Reader is the interface that wraps the basic Read method. (이하 생략)

type Reader interface {
    Read(p []byte) (n int, err error)
}

앞에서 봤던 직렬화 예제 역시 MarshalJSON을 구현하기만 하면 json.Marshaler 인터페이스가 될 수 있으면서 우리가 구현해준 커스텀한 방법으로 직렬화가 가능해지는 것.

 

 

인터페이스 역시 구조체의 내장과 비슷한 형식으로 여러 인터페이스를 합칠 수 있다.

type ReadWriter interface {
    Reader
    Writer
}

이러면 Reader의 모든 메서드와 Writer의 모든 메서드를 구현하는 이름 붙인 자료형은 모두 ReadWriter가 된다.