메소드는 이름을 가진 어떤 타입에 대해서도 정의될 수 있음(포인터와 인터페이스를 제외한)
리시버가 반드시 구조체일 필요는 없음
슬라이스에 대해 살펴볼 때 Append함수를 작성했었는데, 슬라이스에 대한 메소드로 정의해 볼 수 있음
메소드를 바인딩할 타입을 선언한 다음, 메소드의 리시버가 그 타입의 값을 받도록 만듬
type ByteSlice []byte
func (slice ByteSlice) Append(data []byte) []byte {
l := len(slice)
if l + len(data) > cap(slice) { // reallocate
// Allocate double what's needed, for future growth.
newSlice := make([]byte, (l+len(data))*2)
// The copy function is predeclared and works for any slice type.
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:l+len(data)]
copy(slice[l:], data)
return slice
}
func (p *ByteSlice) Append(data []byte) {
slice := *p
// 위쪽의 body 와 똑같이 작성해요. 반환할 필요는 없구요.
*p = slice
}
func (p *ByteSlice) Write(data []byte) (n int, err error) {
slice := *p
// body 는 위랑 똑같아요.
*p = slice
return len(data), nil
}
var b ByteSlice
fmt.Fprintf(&b, "This hour has %d days\\n", 7)