encoding/json 패키지 쓰다보니 커스텀 자료형을 인코딩/디코딩할 일이 생겨서 질문드립니다.
커스텀 자료형을 다룰 때 보통 하는 말이 해당 자료형에 대한 json.Marshler와 json.Unmarshler 인터페이스를 구현하라고 하거든요.
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
그러면 제 생각에는 해당 자료형을 MYTYPE이라치면
func (t MYTYPE) MarshalJSON() ([]byte, error)
func (t MYTYPE) UnmarshalJSON([]byte) error
이렇게 구현해야할 것 같고요.
그런데 UnmarshalJSON을 MYTYPE이 아닌 *MYTYPE에 대해 구현하더라고요
func (t MYTYPE) MarshalJSON() ([]byte, error)
func (t *MYTYPE) UnmarshalJSON([]byte) error
그러면 이건 MYTYPE이 Marshaler와 Unmarshaler 모두를 구현한게 아니라
MYTYPE이 Marshaler를, *MYTPE이 Unmarshaler를 각각 구현한 것 아닌가요?
물론 이렇게 함수를 구현해도 MYTYPE이 MarshalJSON, UnmarshalJSON 메소드를 사용할 수 있다는 것은 압니다.
그리고 UnmarshalJSON은 *MYTYPE에 대해서 구현해야 MYTYPE 자료형의 변수 내용물을 변경할 수 있다는 것도 알고요.
그럼에도 인터페이스 구현과 메소드 사용 가능은 포함 범위가 다른 이야기라 의아해서 질문드립니다.
제 생각에는 해당 타입이 Marshaler를, 해당 타입의 포인터 타입이 Unmarshaler를 구현해야 한다...라는 말이 복잡해서 대충 말하는 거 아닌가 싶기도 한데 어떤지요?
참고)
package main
import "fmt"
type MYPRINTER interface {
PrintOnce()
PrintTwice()
}
type MYTYPE string
func (s MYTYPE) PrintOnce() {
fmt.Println(string(s))
}
func (s *MYTYPE) PrintTwice() {
fmt.Println(string(*s))
fmt.Println(string(*s))
}
func main() {
var s MYTYPE = "Hello, world!"
s.PrintOnce() // no error
s.PrintTwice() // no error
// var p MYPRINTER = s // error, MYTYPE does not implement MYPRINTER (PrintTwice method has pointer receiver)
}
댓글 0