2012-11-06 14 views
46

मैं GAE के लिए एक ऐप लिख कर जाओ सीख रहा हूँ, और यह एक हैंडलर समारोह के हस्ताक्षर है:जाओ HTTP हैंडलर में, ResponseWriter एक मूल्य क्यों है लेकिन एक सूचक अनुरोध करें?

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

मैं सूचक नौसिखिया यहाँ हूँ, तो क्यों Request वस्तु एक सूचक ResponseWriter नहीं है, लेकिन ? क्या इस तरह से इसे रखने की कोई ज़रूरत है या क्या यह किसी प्रकार का उन्नत सूचक आधारित कोड संभव है?

उत्तर

43

w के लिए आपको जो मिलता है वह गैर निर्यात किए गए प्रकार http.response के लिए एक सूचक है लेकिन ResponseWriter एक इंटरफ़ेस है, जो दिखाई नहीं दे रहा है।

server.go से:

type ResponseWriter interface { 
    ... 
} 

दूसरी ओर, r एक ठोस struct करने के लिए एक सूचक है, इसलिए की जरूरत है सटीक यह स्पष्ट रूप:

request.go से:

type Request struct { 
    ... 
} 
20

http.ResponseWriter एक इंटरफ़ेस है, और इस इंटरफ़ेस को लागू करने वाले मौजूदा प्रकार पॉइंटर्स हैं। इसका मतलब है कि इस इंटरफ़ेस में पॉइंटर का उपयोग करने की कोई आवश्यकता नहीं है, क्योंकि यह पहले से ही एक पॉइंटर द्वारा "समर्थित" है। इस अवधारणा को एक डेवेलर्स here में से एक का वर्णन किया गया है, हालांकि http.ResponseWriter को लागू करने वाले एक प्रकार को पॉइंटर होने की आवश्यकता नहीं थी, यह व्यावहारिक नहीं होगा, कम से कम http सर्वर के भीतर नहीं।

http.Request एक इंटरफ़ेस नहीं है, यह केवल एक संरचना है, और चूंकि हम इस संरचना को बदलना चाहते हैं और वेब सर्वर उन परिवर्तनों को देखना चाहते हैं, इसे एक सूचक होना चाहिए। अगर यह सिर्फ एक संरचना मूल्य था, तो हम इसकी एक प्रतिलिपि बस संशोधित करेंगे कि हमारे कोड को कॉल करने वाला वेब सर्वर नहीं देख सका।

+1

मुझे नहीं लगता कि यह सही है। पॉइंटर्स के पीछे के मान इंटरफेस को वैल्यू के समान ही कार्यान्वित कर सकते हैं, इसलिए यहां भेद की आवश्यकता नहीं है। आधार प्रकार int के साथ एक प्रकार एक सूचक होने के बिना एक इंटरफेस को संतुष्ट कर सकता है या एक द्वारा समर्थित किया जा सकता है। – nemo

+1

खैर, मेरा मतलब यह नहीं था कि इंटरफ़ेस को लागू करने वाली _all_ चीजें पॉइंटर्स होंगी।कुछ प्रतिक्रिया करने के लिए इंटरफ़ेस के पीछे मूल्य की स्थिति को संशोधित करने की आवश्यकता होगी, और उस मूल्य की आवश्यकता होगी एक सूचक प्रकार (जैसा कि ब्लॉग पोस्ट I से भी जुड़ा हुआ है)। लेकिन हाँ, http.ResponseWriter सैद्धांतिक रूप से एक int द्वारा कार्यान्वित किया जा सकता है (जिनकी विधियां उस int मान को कभी नहीं बदल सकती हैं)। – nos

0

मुझे लगता है कि Request ऑब्जेक्ट को पॉइंटर के रूप में पारित करने का मुख्य कारण Body फ़ील्ड है। किसी दिए गए HTTP अनुरोध के लिए, शरीर केवल एक बार पढ़ सकता है। यदि Request ऑब्जेक्ट क्लोन किया गया था, क्योंकि यह होगा कि यह सूचक के रूप में पारित नहीं किया गया था, तो हमारे पास शरीर से कितना पढ़ा गया है, इस बारे में अलग-अलग जानकारी के साथ दो ऑब्जेक्ट होंगे।

0

यह अनुरोध करने का सूचक क्यों है सरल: हैंडलर द्वारा अनुरोध में परिवर्तन सर्वर पर दिखाई देने की आवश्यकता है, इसलिए हम केवल मूल्य के बजाय संदर्भ द्वारा इसे पास कर रहे हैं।

यदि आप नेट/http लाइब्रेरी कोड में खोदते हैं, तो आप पाएंगे कि ResponseWriter एक गैर-आयातित संरचना प्रतिक्रिया के लिए एक इंटरफ़ेस है, और हम संदर्भ द्वारा संरचना को पार कर रहे हैं (हम प्रतिक्रिया के लिए एक सूचक में गुजर रहे हैं) और मूल्य से नहीं। ResponseWriter एक इंटरफ़ेस है जो एक हैंडलर HTTP प्रतिक्रिया बनाने के लिए उपयोग करता है। प्रतिक्रिया संरचना का समर्थन करने वाला वास्तविक संरचना गैर-निर्यातित संरचना http.response है। क्योंकि यह कोई भी निर्यात नहीं है, आप इसे सीधे उपयोग नहीं कर सकते हैं; आप केवल ResponseWriter इंटरफ़ेस के माध्यम से इसका उपयोग कर सकते हैं।

दूसरे शब्दों में, दोनों पैरामीटर संदर्भ द्वारा पारित किए जाते हैं; यह सिर्फ यह है कि विधि हस्ताक्षर एक ResponseWriter लेता है जो एक सूचक के लिए एक सूचक के लिए एक इंटरफेस है, इसलिए ऐसा लगता है कि यह मूल्य द्वारा पारित किया गया है।