2015-06-30 2 views
2
package main 

import (
    "net/http" 
) 

func main() { 
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ 
     w.Write([]byte("hello world")) 
    }) 
    http.ListenAndServe(":8000", nil) 
} 

Если удалить * в http.Request:Почему аргумент http.Request должен быть указателем?

github.com/creating_web_app_go/main.go:8: не может использовать Func буквального (тип FUNC (http.ResponseWriter, http.Request)) как тип func (http.ResponseWriter, * http.Request) в аргументе http.HandleFunc

Я очень новичок и для Go, и для указателей.

Вопрос в том, почему должен http.Request быть указателем, а не func literal? Может ли кто-нибудь объяснить это самым простым способом, возможно, с ссылкой на исходный код?

+0

Почему -1? Это действительно плохо заданный вопрос? –

+0

На самом деле это очень хороший вопрос imo – Yar

ответ

8

Потому что это большая структура. Копирование было бы дорого. Таким образом, это указатель на структуру, которая является общей в Go, когда структуры большие. Кроме того, он имеет некоторое состояние, поэтому, вероятно, он будет запутан, если он будет скопирован. Было бы бессмысленно быть литералом func; Я не понимаю, почему это вариант.

+0

Да, литерал func был просто ошибкой, которую она выбрасывает, когда вы не устанавливаете ее как указатель. –

2

Так как это работает. У них есть аргументы, и когда вы вызываете их, вы должны предоставить необходимые аргументы. Типы должны быть одинаковыми.

Я думаю, что вы действительно спрашиваете; Почему он спроектирован таким образом?

Потому что вы предоставляете делегат для http.HandleFunc для вызова, когда запрос делается на корень "/". В большинстве случаев, когда API RESTful обрабатывает запрос, ему нужно знать информацию в запросе, такие как заголовки, параметры запроса и/или тело сообщения ... Если вы не хотите использовать эту информацию, t должен, это не много накладных, чтобы передать ссылку в функцию. Но практически для каждого конкретного случая использования данные необходимы, чтобы они включались, поэтому он внесен в предоставленный вами делегат. Из перцептивной их реализации им нужно знать, что такое подпись метода, которую вы предоставляете, чтобы они могли ее вызывать.

Так, чтобы уточнить, то, что вы ищете, является необходимой сигнатурой для func, которую вы предоставляете в качестве второго аргумента http.HandleFunc. Первый аргумент - это путь. Он вызывает этот метод, когда HTTP-запрос выполняется по предоставленному пути. Этот код будет вызывать этот аргумент, который вызывает его handler, и ему требуется согласованное определение, чтобы оно могло делать handler(resp, req) и не нужно было делать отражение или переключатель или какой-либо другой поток управления, чтобы вызвать ваш код.

+1

Множество вкусных бит в этом, что я должен будет погрузиться в деле делегирования, отражения, потока управления lol, но я предполагаю, что это самый правильный ответ. Спасибо за ваши старания! Я все выясню :) –

+1

@MatthewHarwood не забыл, что мое описание довольно абстрактно. Сам код, который делает это, находится здесь; http://golang.org/src/net/http/server.go, если вы хотите увидеть, что на самом деле делает 'HandleFunc', с аргументом' func (w http.ResponseWriter, r * http.Request) '. Также обратите внимание, что вы можете определить функцию с этим sig, как правило, в другом месте и передать его по имени. – evanmcdonnal

Смежные вопросы