102 votes

Dans les gestionnaires HTTP de Go, pourquoi le ResponseWriter est-il une valeur mais la Request un pointeur ?

J'apprends le Go en écrivant une application pour GAE, et ceci est la signature d'une fonction handler :

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

Je suis un pointeur débutant ici, alors pourquoi est-ce que le Request un pointeur, mais l'objet ResponseWriter pas ? Est-il nécessaire de procéder de cette façon ou est-ce seulement pour rendre possible une sorte de code avancé basé sur les pointeurs ?

83voto

dystroy Points 145126

Ce que vous obtenez pour w est un pointeur vers le type non exporté http.response mais comme ResponseWriter est une interface, ce n'est pas visible.

De server.go :

type ResponseWriter interface {
    ...
}

D'un autre côté, r est un pointeur vers une structure concrète, d'où la nécessité de passer une référence explicitement.

De demande.go :

type Request struct {
    ...
}

35voto

nos Points 102226

En http.ResponseWriter est une interface, et les types existants implémentant cette interface sont des pointeurs. Cela signifie qu'il n'est pas nécessaire d'utiliser un pointeur vers cette interface, car elle est déjà "soutenue" par un pointeur. Ce concept est décrit en détail par l'un des développeurs de Go. aquí Bien qu'un type implémentant http.ResponseWriter n'ait pas besoin d'être un pointeur, il ne serait pas pratique, du moins pas au sein du serveur http de Go.

http.Request n'est pas une interface, c'est juste un struct, et puisque nous voulons modifier ce struct et faire en sorte que le serveur web voit ces changements, il doit être un pointeur. S'il s'agissait d'une simple valeur de structure, nous modifierions simplement une copie de celle-ci que le serveur Web appelant notre code ne pourrait pas voir.

2voto

X. Wang Points 338

La raison pour laquelle il s'agit d'un pointeur vers Request est simple : les changements apportés à Request par le gestionnaire doivent être visibles pour le serveur, donc nous le passons uniquement par référence plutôt que par valeur.

Si vous creusez dans le code de la bibliothèque net/http, vous constaterez que ResponseWriter est une interface vers une struct response non exportée, et que nous passons la struct par référence (nous passons un pointeur vers la réponse) et non par valeur. ResponseWriter est une interface qu'un gestionnaire utilise pour créer une réponse HTTP. La structure réelle qui soutient ResponseWriter est la structure nonexportée http.response. Parce qu'elle n'est pas exportée, vous ne pouvez pas l'utiliser directement ; vous ne pouvez l'utiliser qu'à travers l'interface ResponseWriter.

En d'autres termes, les deux paramètres sont transmis par référence ; c'est juste que la signature de la méthode prend un ResponseWriter qui est une interface vers un pointeur vers une structure, de sorte qu'il semble être transmis par valeur.

1voto

md2perpe Points 790

Je pense que la principale raison de la Request à passer comme un pointeur est l'objet Body champ. Pour une requête HTTP donnée, le corps ne peut être lu qu'une seule fois. Si le Request a été cloné, comme ce serait le cas s'il n'était pas passé comme un pointeur, nous aurions deux objets avec des informations différentes sur la quantité lue dans le corps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X