안녕하세요, 주니어 개발자 Eon입니다.
이번에 다룰 내용은 메서드입니다.
메서드는 함수와 큰 차이가 없으나, 객체에 속한다는 특징이 있습니다.
함수는 객체와 상관없이 호출하면 사용이 가능하지만, 메서드는 해당 객체를 통해서만 호출이 가능합니다.
package main
import "fmt"
type Parameter struct {
XX string
}
func nameOfFunction(p *Parameter) {
p.XX = "YY"
}
func main() {
p := Parameter{}
p.XX = "XX"
nameOfFunction(&p)
fmt.Println(p)
}
package main
import "fmt"
type Receiver struct {
XX string
}
func (r *Receiver) nameOfMethod() {
r.XX = "YY"
}
func main() {
r := Receiver{}
r.XX = "XX"
r.nameOfMethod()
fmt.Println(r)
}
그렇다면 왜 제약조건이 더 붙은 메서드를 사용할까?
유지보수 측면에서 더 유리할 수 있습니다.
프로그램이 동작하는 데에 있어서는 큰 차이가 없으나, 객체의 타입마다 사용할 수 있는 메서드를 제한할 수 있습니다.
메서드는 위에 함수와 다르게 함수명과 함수 선언부 사이에 리시버가 들어갑니다.
Receiver
는 어떤 타입의 객체가 사용할 수 있는 메서드인지 제한하고, 해당 타입의 객체만 이 메서드를 사용할 수 있게 합니다.func (s *Student) StudentInfoUpdate() { // TODO: update student's information ... }
여기서
StudentInfoUpdate()
라는 메서드는Student
라는 타입의리시버
가 지정되어 있습니다.
Student
객체 말고는 이 메서드를 사용할 수 없습니다.
함수와 마찬가지로 포인터형과 밸류형이 있습니다.
포인터형은 당연하게도 인스턴스
를 직접 조작합니다.
밸류형은 값을 복사해서 사용하기 때문에 포인터형과 다르게 인스턴스
를 새로 만들어서 조작합니다.
package main
import "fmt"
type Student struct {
Name string
Age int8
Email string
}
func (s *Student) HappyNewYear() {
s.Age += 1
}
func (s *Student) UpdateEmail(NewEmail string) {
s.Email = NewEmail
}
func main() {
s1 := new(Student)
s1.Name = "David"
s1.Age = 20
s1.Email = "empty@email.invalid"
s1.HappyNewYear()
s1.UpdateEmail("david@email.com")
fmt.Println(*s1)
}
/* output
{David 21 david@email.com}
*/
위와 같이 반환값이 없어도 포인터
로 인스턴스
를 직접 조작하기 때문에 변경된 값이 유지되는 것을 볼 수 있습니다.
package main
import "fmt"
type Student struct {
Name string
Age int8
Email string
}
func (s Student) HappyNewYear() {
s.Age += 1
}
func (s Student) UpdateEmail(NewEmail string) {
s.Email = NewEmail
}
func main() {
s2 := Student{}
s2.Name = "David"
s2.Age = 20
s2.Email = "empty@email.invalid"
s2.HappyNewYear()
s2.UpdateEmail("david@email.com")
fmt.Println(s2)
}
/* output
{David 20 empty@email.invalid}
*/
위와 같이 반환하지 않고 객체를 밸류형으로 조작하는 경우, 호출된 메서드에서
새로운 인스턴스
가 만들어집니다.func (s Student) UpdateEmail(NewEmail string) { s.Email = NewEmail fmt.Println(s.Email) } /* output david@email.com */
이렇게
UpdateEmail()
메서드 내에서는 값이 정상적으로 변경된 것을 확인할 수 있습니다.
값 반환을 하지 않았기 때문에 해당 메서드 내에서 변경된 값은 의도한s2
객체에 아무런 영향을 주지 않습니다.
package main
import "fmt"
type Student struct {
Name string
Age int8
Email string
}
func (s Student) HappyNewYear() Student {
s.Age += 1
return s
}
func (s Student) UpdateEmail(NewEmail string) string {
s.Email = NewEmail
return s.Email
}
func main() {
s2 := Student{}
s2.Name = "David"
s2.Age = 20
s2.Email = "empty@email.invalid"
s2 = s2.HappyNewYear()
s2.Email = s2.UpdateEmail("david@email.com")
fmt.Println(s2)
}
/* output
{David 21 david@email.com}
*/
위와 같이 알맞게 값을 반환했더니 의도한 대로 Age
와 Email
이 변경된 것을 확인할 수 있습니다.
이번 포스트는 메서드에 대한 내용이었습니다.
감사합니다.👍
좋은 글 감사합니다!!