go 언어 학습 노트 (12) - 구조 체

4198 단어 golang
프롤로그
구조 체 유형 은 데이터 구 조 를 나타 내 며 정확 한 이름과 유형 을 가 진 필드 를 포함 할 수 있 습 니 다.우 리 는 이러한 유형 을 위해 몇 가지 방법 을 연결 할 수 있 는데, 여 기 는 방법 을 함수 의 특수 버 전 으로 볼 수 있다.함 수 는 이름 이 없고 값 으로 볼 수 있 으 며 방법 은 이 두 가지 특성 이 없 으 며 가장 중요 한 것 은 방법 이 반드시 특정한 방법 에 예속 되 어야 한 다 는 것 이다.방법 이 속 한 유형 은 성명 의 수신 자 성명 을 통 해 나타난다.
우 리 는 구조 체 유형 (struct) 중의 한 필드 를 이 구조 체 유형의 속성 이나 데이터 로 보고 그 에 속 하 는 방법 을 그 중의 데이터 에 부가 하 는 조작 으로 볼 수 있다.
속성 과 조작 을 한데 묶 는 것 은 대상 을 대상 으로 프로 그래 밍 (OOP) 하 는 주요 원칙 이다.
Go 언어 는 이런 패 키 징 방법 을 추천 합 니 다.
성명
구조 체 형식의 한 필드 성명 에 하나의 유형 만 있다 면 이 필드 는 무엇 을 대표 합 니까?
type AnimalCategory struct {
	kingdom string //  。
	phylum  string //  。
	class   string //  。
	order   string //  。
	family  string //  。
	genus   string //  。
	species string //  。
}


type Animal struct {
	scientificName string //   。
	AnimalCategory        //       。
}

상기 예제 에서 Animal 형식의 필드 성명 Animal Category 는 무엇 을 대표 합 니까?
필드 설명 Animal Category 는 Animal 형식의 '끼 워 넣 기 필드' 를 대표 합 니 다.
한 필드 의 성명 에 필드 의 형식 만 있 고 이름 이 없다 면, 그것 은 삽입 필드 나 익명 필드 라 고 합 니 다.
우 리 는 이 형식 (Animal) 변수의 이름 뒤 꿈 치 를 통 해 "..." 다음 에 필드 형식 을 삽입 하 는 방식 으로 이 필드 를 참조 할 수 있 습 니 다. 예 를 들 어:
a.AnimalCategory.String()
이 를 통 해 알 수 있 듯 이 삽입 필드 의 유형 은 유형 이자 이름 (직접 참조 할 수 있 음) 이다.
여기 서 이런 용법 은 마치 계승 을 실현 한 것 같다.
그렇다면 Go 언어 는 삽 입 된 필드 로 OOP 의 계승 을 실현 한 것 일 까?
Go 언어 는 OOP 라 는 계승 개념 없 이 필드 에 끼 워 넣 는 방식 으로 유형 간 조합 을 실현 했다.
OOP 의 계승 은 코드 의 간결 성 을 희생 하여 확장 성 을 바 꾸 는 것 이 고 이러한 확장 성 은 부모 클래스 에 침입 하 는 방식 으로 이 루어 진다.
유형 간 의 조합 은 시비 성명 방식 을 사용 합 니 다. 우 리 는 특정한 유형 이 특정한 인 터 페 이 스 를 실현 하거나 한 유형 이 다른 유형 을 계승 했다 고 명시 할 필요 가 없습니다.
유형 간 조합 도 비 침입 식 (OOP 와 다 름) 으로 유형의 패 키 징 을 파괴 하거나 유형 간 결합 을 가중 시 키 지 않 습 니 다.
유형 간 의 조합 도 유연 하 다. 필드 를 삽입 하 는 방식 으로 한 유형의 속성 과 능력 (조작) 을 다른 유형 에 접목 시 킬 수 있다.이렇게 해서 끼 워 넣 은 형식 은 끼 워 넣 은 필드 가 실현 하 는 인 터 페 이 스 를 실현 한다.
Go 원인의 유형 조합 은 OOP 의 계승 보다 더욱 간결 하고 뚜렷 하 며 여러 필드 를 삽입 하여 기능 이 강 한 유형 을 쉽게 실현 할 수 있 지만 그렇게 복잡 한 차원 구조 와 상당 한 관리 원 가 를 다 중 계승 하지 않 습 니 다.
인터페이스 유형 간 에 도 조합 할 수 있 고 흔히 볼 수 있 습 니 다. 우 리 는 이 를 통 해 인터페이스 가 정의 하 는 행동 이나 인터페이스의 특징 을 확장 합 니 다.
값 방법 과 지침 방법
type user struct {
 name string
 email string 
} 
//      
func (u user) notify() {
 log.Printf("sending User Email to %s
", u.name, u.email) } // func (u *user) notifyPointer() { log.Printf("sending User Email to %s
", u.name, u.email) }

일반적인 함수 에 비해 또 다른 점 이 있 습 니 다. 값 수신 자가 설명 하 는 방법 은 호출 할 때 이 값 의 사본 을 사용 하여 실 행 됩 니 다. 포인터 수신 자 는 호출 방법 을 공유 할 때 수신 자가 가리 키 는 값, 즉 가리 키 는 값 을 수정 할 수 있 습 니 다.사용 할 때 값 형식의 수신 자 도 포인터 형식의 호출 을 사용 할 수 있 습 니 다. 다음 과 같 습 니 다.
func (u user) notify() {
  log.Printf("sending User Email to %s
", u.name, u.email) } func main() { tom := &user{"tom", "[email protected]"} tom.notify() }

 
사실 Go 의 코드 뒤에 이미 이 유형 을 바 꾸 었 습 니 다.
(*tom).notify()

그래서 다음 과 같은 대조 관계 가 있 습 니 다.
방법 수신 자
실제 사용 가능 유형
(t T)
T and *T
(t *T)
*T
따라서 다음 코드 가 실 행 될 때 오류 가 발생 할 수 있 습 니 다.
package main

import (
    "log"
)

type notifier interface {
    notify()
}

type user struct {
    name  string
    email string
}

func (u *user) notify() {
    log.Printf("Sending user email to %s", u.name)
}

func main() {
    u := user{"Bill", "[email protected]"}

    sendNotification(u)
}
func sendNotification(n notifier) {
    n.notify()
}

실행 결과
# command-line-arguments
./main.go:23: cannot use u (type user) as type notifier in argument to sendNotification:
        user does not implement notifier (notify method has pointer receiver)

사고 문제
1. 우 리 는 구조 체 유형 에 특정한 유형의 지침 유형 을 삽입 할 수 있 습 니까?가능 하 다 면 어떤 주의사항 이 있 습 니까?
답: 우 리 는 구조 체 에 특정한 유형의 지침 유형 을 삽입 할 수 있 습 니 다. 일반 지침 과 유사 합 니 다. 기본 값 은 nil 로 초기 화 되 었 기 때문에 사용 하기 전에 초기 화 를 해 야 합 니 다. 그렇지 않 으 면 오류 가 발생 할 수 있 습 니 다.
2. 하위 디 렉 터 리 struct {} 은 무엇 을 대표 합 니까?또 무슨 소 용이 있 습 니까?
답: 빈 구조 체 는 메모리 공간 을 차지 하지 않 지만 구조 체 의 모든 속성 을 가지 고 있 습 니 다. 방법 이 있 으 면 channel 에 쓸 수 있 습 니 다.그래서 구조 체 를 사용 해 야 하고 구체 적 인 속성 이 필요 하지 않 을 때 사용 할 수 있다.

좋은 웹페이지 즐겨찾기