프로그래밍/golang
ultimate in go (5)- data structure(embedding)
나도한강뷰
2023. 1. 24. 00:06
임베딩
임베딩이 아닌 필드 선언
type user struct {
name string
email string
}
func (u *user) notify() {
fmt.Printf("Sending user email To %s<%s>\n", u.name, u.email)
}
type admin struct {
person user // 임베딩이 아니다.
level string
}
func main() {
ad := admin{
person: user{
name: "Hoanh An",
email: "hoanhan101@gmail.com",
},
level: "superuser",
}
}
ad.person.notify()
- admin의 user는 임베딩이 아닌, 하나의 필드를 user라는 타입으로 정의한것
- admin을 리터럴로 선언한 이후 내부 user또한 리터럴로 선언해 주어야된다.
- 이럴경우 method를 쓰는 경우 참조는 ad.person.notify같이 모든 구조에 대한 언급이 필요하다.
임베딩 타입
type user struct {
name string
email string
}
func (u *user) notify() {
fmt.Printf("Sending user email To %s<%s>\n", u.name, u.email)
}
type admin struct {
user // 임베딩 타입
level string
}
func main() {
ad := admin{
user: user{
name: "Hoanh An",
email: "hoanhan101@gmail.com",
},
level: "superuser",
}
// 내부 타입 메서드를 직접 사용 가능하다.
ad.user.notify()
ad.notify()
}
- 다음과 같이 임베딩 타입을 쓰게되면 inner type이 승격하게 된다.
- 그말은 user의 내부 필드값을 ad.user.name이라고 쓰지않고 ad.name이라고 선언할 수 있는 것과 같다.
- 그말은 내부 타입과 관련된 모든 것들을 외부 타입에서도 사용할 수 있도록 승격한다는 것과 같다.
- 임베딩은 서브타입관계를 생성하지않고 admin은 admin, user는 user로 작동한다.
- 다만 외부타입이 사용할 수 있도록 내부타입을 노출시킬 뿐이다.
동일한 인터페이스가 구현되어 있는 내 외부 타입
type notifier interface {
notify()
}
type user struct {
name string
email string
}
func (u *user) notify() {
fmt.Printf("Sending user email To %s<%s>\n", u.name, u.email)
}
type admin struct {
user
level string
}
func (a *admin) notify() {
fmt.Printf("Sending admin email To %s<%s>\n", a.name, a.email)
}
func main() {
ad := admin{
user: user{
name: "Hoanh An",
email: "hoanhan101@gmail.com",
},
level: "superuser",
}
}
sendNotification(&ad)
ad.user.notify()
ad.notify()
- 외부에서 이미 정의된게 있다면, 내부에서 승격은 이루어지지 않고 덮여쓰여진다.
- 그럼에도 불구하고 내부타입의 매소드를 쓰고싶다면 직접적으로 ad.user.notify같이 써줘야된다.
- ad.notify로 쓰면 외부타입의 매소드를 사용하게 된다.
exporting(내보내기)
- 간단함으로 생략
- package를 통해서 명칭 선언
- 대문자 외부 노출
- 소문자 외부 노출x
- 하지만 함수나 외부에 노출되는 방식 내부에는 외부 노출되지않는것을 사용하여도 에러x
- struct선언이나 embedding에도 동일하게 적용
- 그러나 직접 내외부 노출을 결정하는게 좋음