IT Share you

Go HTTP 핸들러에서 ResponseWriter는 값이지만 Request는 포인터 인 이유는 무엇입니까?

shareyou 2020. 11. 8. 11:31
반응형

Go HTTP 핸들러에서 ResponseWriter는 값이지만 Request는 포인터 인 이유는 무엇입니까?


저는 GAE 용 앱을 작성하여 Go를 배우고 있으며 이것은 핸들러 함수의 서명입니다.

func handle(w http.ResponseWriter, r *http.Request) {}

나는 여기서 포인터 초보자인데 왜 Request객체가 포인터가 ResponseWriter아닌가? 이런 식으로 할 필요가 있습니까? 아니면 일종의 고급 포인터 기반 코드를 가능하게 만드는 것입니까?


당신이 얻는 w것은 내 보내지 않은 유형에 대한 포인터 http.response이지만 ResponseWriter인터페이스와 마찬가지로 보이지 않습니다.

에서 server.go :

type ResponseWriter interface {
    ...
}

반면에는 r구체적인 구조체에 대한 포인터이므로 명시 적으로 정밀해야 할 필요가 있습니다.

에서 request.go :

type Request struct {
    ...
}

http.ResponseWriter인터페이스이며,이 인터페이스를 구현하는 기존의 유형에 대한 포인터입니다. 이는 이미 포인터에 의해 "백업"되어 있으므로이 인터페이스에 대한 포인터를 사용할 필요가 없음을 의미합니다. 이 개념은 여기 에서 go 개발자 중 한 명이 설명합니다. http.ResponseWriter를 구현하는 유형이 포인터가 될 필요는 없지만 적어도 go http 서버 내에서는 실용적이지 않습니다.

http.Request은 인터페이스가 아니라 구조체 일뿐입니다.이 구조체를 변경하고 웹 서버가 이러한 변경 사항을 확인하도록하려면 포인터가되어야합니다. 단지 구조체 값이라면 우리 코드를 호출하는 웹 서버가 볼 수없는 복사본을 수정하면됩니다.


Request에 대한 포인터 인 이유는 간단합니다. 핸들러에 의한 Request 변경 사항은 서버에 표시되어야하므로 값 대신 참조로만 전달합니다.

net / http 라이브러리 코드를 자세히 살펴보면 ResponseWriter가 내 보내지 않은 구조체 응답에 대한 인터페이스이고 값이 아닌 참조로 구조체를 전달한다는 것을 알 수 있습니다 (응답에 대한 포인터를 전달 함). . ResponseWriter는 핸들러가 HTTP 응답을 생성하는 데 사용하는 인터페이스입니다. ResponseWriter를 백업하는 실제 구조체는 내 보내지 않은 http.response 구조체입니다. 수출되지 않기 때문에 직접 사용할 수 없습니다. ResponseWriter 인터페이스를 통해서만 사용할 수 있습니다.

즉, 두 매개 변수가 모두 참조로 전달됩니다. 메서드 시그니처가 구조체에 대한 포인터에 대한 인터페이스 인 ResponseWriter를 사용하기 때문에 마치 값으로 전달 된 것처럼 보입니다.


여기와 다른 곳에서 다른 많은 답변에서 올바르게 언급했듯이 ResponseWriter인터페이스이며 이에 대한 의미는 SO 답변 및 블로그 에 자세히 설명되어 있습니다.

(그런 일이 실제로 존재하지 않지만 내가 주소로하고자하는 이유 요청 "참조"에 의해 전달하는 큰 위험 - 오해, 여기에 내가 느낌이다 이동 ) 우리가 변경하려면 "이다 서버에 표시됩니다. "

다른 사람들의 몇 가지 답변을 인용합니다.

[..] 그냥 구조체, 그리고 우리는이 구조체를 변경하고 웹 서버가 변경 사항을보고 갖고 싶어하기 때문에, 포인터를 수있다 [..] SO

우리는 단지 값 대신에 참조로 전달되도록하는 [...] 서버에 표시되도록 핸들러 필요에 의해 변경 요구에 [...] SO

이것은 잘못된 것입니다 . 실제로 문서는 요청을 변조 / 변이하는 것에 대해 명시 적으로 경고합니다 .

본문을 읽는 경우를 제외하고 핸들러는 제공된 요청을 수정해서는 안됩니다.

그 반대 죠? :-)

미들웨어 체인의 다음 핸들러로 전달하기 전에 추적 헤더를 추가하는 등 요청을 변경하려면 요청 을 복사 하고 복사 된 버전을 체인 아래로 전달해야합니다.

사람들에게 요청을 변경하지 말라고 명시 적으로 지시하는 경우 왜 포인터를 사용합니까? 성능 , Request큰 구조체이며 특히 마음에 긴 미들웨어 체인, 성능이 가져올 수있는 복사. 팀은 균형을 유지해야했지만 이상적인 솔루션은 아니지만 여기서는 성능 측면에서 절충안이 분명합니다 (API 안전성 대신).


Request객체가 포인터로 전달되는 주된 이유 Body필드 라고 생각 합니다. 주어진 HTTP 요청에 대해 본문은 한 번만 읽을 수 있습니다. 경우 Request개체가 복제 된,이 포인터로 전달되지 않은 경우가있을 것입니다, 우리는 몸에서 읽은 양에 대한 다양한 정보를 두 개체있을 것입니다.

참고 URL : https://stackoverflow.com/questions/13255907/in-go-http-handlers-why-is-the-responsewriter-a-value-but-the-request-a-pointer

반응형