Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Delta Between Two Patch Sets: doc/effective_go.html

Issue 2310041: code review 2310041: Effective Go: update for new http interface. (Closed)
Left Patch Set: Created 14 years, 5 months ago
Right Patch Set: code review 2310041: Effective Go: update for new http interface. Created 14 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 <!-- Effective Go --> 1 <!-- Effective Go -->
2 2
3 <h2 id="introduction">Introduction</h2> 3 <h2 id="introduction">Introduction</h2>
4 4
5 <p> 5 <p>
6 Go is a new language. Although it borrows ideas from 6 Go is a new language. Although it borrows ideas from
7 existing languages, 7 existing languages,
8 it has unusual properties that make effective Go programs 8 it has unusual properties that make effective Go programs
9 different in character from programs written in its relatives. 9 different in character from programs written in its relatives.
10 A straightforward translation of a C++ or Java program into Go 10 A straightforward translation of a C++ or Java program into Go
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 set up. Here's a trivial but complete implementation of a handler to 1871 set up. Here's a trivial but complete implementation of a handler to
1872 count the number of times the 1872 count the number of times the
1873 page is visited. 1873 page is visited.
1874 </p> 1874 </p>
1875 <pre> 1875 <pre>
1876 // Simple counter server. 1876 // Simple counter server.
1877 type Counter struct { 1877 type Counter struct {
1878 n int 1878 n int
1879 } 1879 }
1880 1880
1881 func (ctr *Counter) ServeHTTP(c http.ResponseWriter, req *http.Request) { 1881 func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
rsc1 2010/09/29 18:02:58 Probably change all the c to w.
1882 ctr.n++ 1882 ctr.n++
1883 fmt.Fprintf(c, "counter = %d\n", ctr.n) 1883 fmt.Fprintf(w, "counter = %d\n", ctr.n)
1884 } 1884 }
1885 </pre> 1885 </pre>
1886 <p> 1886 <p>
1887 (Keeping with our theme, note how <code>Fprintf</code> can print to an HTTP conn ection.) 1887 (Keeping with our theme, note how <code>Fprintf</code> can print to an
rsc1 2010/09/29 18:02:58 to a ResponseWriter.
1888 <code>http.ResponseWriter</code>.)
1888 For reference, here's how to attach such a server to a node on the URL tree. 1889 For reference, here's how to attach such a server to a node on the URL tree.
1889 <pre> 1890 <pre>
1890 import "http" 1891 import "http"
1891 ... 1892 ...
1892 ctr := new(Counter) 1893 ctr := new(Counter)
1893 http.Handle("/counter", ctr) 1894 http.Handle("/counter", ctr)
1894 </pre> 1895 </pre>
1895 <p> 1896 <p>
1896 But why make <code>Counter</code> a struct? An integer is all that's needed. 1897 But why make <code>Counter</code> a struct? An integer is all that's needed.
1897 (The receiver needs to be a pointer so the increment is visible to the caller.) 1898 (The receiver needs to be a pointer so the increment is visible to the caller.)
1898 </p> 1899 </p>
1899 <pre> 1900 <pre>
1900 // Simpler counter server. 1901 // Simpler counter server.
1901 type Counter int 1902 type Counter int
1902 1903
1903 func (ctr *Counter) ServeHTTP(c http.ResponseWriter, req *http.Request) { 1904 func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
1904 *ctr++ 1905 *ctr++
1905 fmt.Fprintf(c, "counter = %d\n", *ctr) 1906 fmt.Fprintf(w, "counter = %d\n", *ctr)
1906 } 1907 }
1907 </pre> 1908 </pre>
1908 <p> 1909 <p>
1909 What if your program has some internal state that needs to be notified that a pa ge 1910 What if your program has some internal state that needs to be notified that a pa ge
1910 has been visited? Tie a channel to the web page. 1911 has been visited? Tie a channel to the web page.
1911 </p> 1912 </p>
1912 <pre> 1913 <pre>
1913 // A channel that sends a notification on each visit. 1914 // A channel that sends a notification on each visit.
1914 // (Probably want the channel to be buffered.) 1915 // (Probably want the channel to be buffered.)
1915 type Chan chan *http.Request 1916 type Chan chan *http.Request
1916 1917
1917 func (ch Chan) ServeHTTP(c http.ResponseWriter, req *http.Request) { 1918 func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) {
1918 ch &lt;- req 1919 ch &lt;- req
1919 fmt.Fprint(c, "notification sent") 1920 fmt.Fprint(w, "notification sent")
1920 } 1921 }
1921 </pre> 1922 </pre>
1922 <p> 1923 <p>
1923 Finally, let's say we wanted to present on <code>/args</code> the arguments 1924 Finally, let's say we wanted to present on <code>/args</code> the arguments
1924 used when invoking the server binary. 1925 used when invoking the server binary.
1925 It's easy to write a function to print the arguments. 1926 It's easy to write a function to print the arguments.
1926 </p> 1927 </p>
1927 <pre> 1928 <pre>
1928 func ArgServer() { 1929 func ArgServer() {
1929 for i, s := range os.Args { 1930 for i, s := range os.Args {
1930 fmt.Println(s) 1931 fmt.Println(s)
1931 } 1932 }
1932 } 1933 }
1933 </pre> 1934 </pre>
1934 <p> 1935 <p>
1935 How do we turn that into an HTTP server? We could make <code>ArgServer</code> 1936 How do we turn that into an HTTP server? We could make <code>ArgServer</code>
1936 a method of some type whose value we ignore, but there's a cleaner way. 1937 a method of some type whose value we ignore, but there's a cleaner way.
1937 Since we can define a method for any type except pointers and interfaces, 1938 Since we can define a method for any type except pointers and interfaces,
1938 we can write a method for a function. 1939 we can write a method for a function.
1939 The <code>http</code> package contains this code: 1940 The <code>http</code> package contains this code:
1940 </p> 1941 </p>
1941 <pre> 1942 <pre>
1942 // The HandlerFunc type is an adapter to allow the use of 1943 // The HandlerFunc type is an adapter to allow the use of
1943 // ordinary functions as HTTP handlers. If f is a function 1944 // ordinary functions as HTTP handlers. If f is a function
1944 // with the appropriate signature, HandlerFunc(f) is a 1945 // with the appropriate signature, HandlerFunc(f) is a
1945 // Handler object that calls f. 1946 // Handler object that calls f.
1946 type HandlerFunc func(ResponseWriter, *Request) 1947 type HandlerFunc func(ResponseWriter, *Request)
1947 1948
1948 // ServeHTTP calls f(c, req). 1949 // ServeHTTP calls f(c, req).
1949 func (f HandlerFunc) ServeHTTP(c ResponseWriter, req *Request) { 1950 func (f HandlerFunc) ServeHTTP(w ResponseWriter, req *Request) {
1950 f(c, req) 1951 f(w, req)
1951 } 1952 }
1952 </pre> 1953 </pre>
1953 <p> 1954 <p>
1954 <code>HandlerFunc</code> is a type with a method, <code>ServeHTTP</code>, 1955 <code>HandlerFunc</code> is a type with a method, <code>ServeHTTP</code>,
1955 so values of that type can serve HTTP requests. Look at the implementation 1956 so values of that type can serve HTTP requests. Look at the implementation
1956 of the method: the receiver is a function, <code>f</code>, and the method 1957 of the method: the receiver is a function, <code>f</code>, and the method
1957 calls <code>f</code>. That may seem odd but it's not that different from, say, 1958 calls <code>f</code>. That may seem odd but it's not that different from, say,
1958 the receiver being a channel and the method sending on the channel. 1959 the receiver being a channel and the method sending on the channel.
1959 </p> 1960 </p>
1960 <p> 1961 <p>
1961 To make <code>ArgServer</code> into an HTTP server, we first modify it 1962 To make <code>ArgServer</code> into an HTTP server, we first modify it
1962 to have the right signature. 1963 to have the right signature.
1963 </p> 1964 </p>
1964 <pre> 1965 <pre>
1965 // Argument server. 1966 // Argument server.
1966 func ArgServer(c http.ResponseWriter, req *http.Request) { 1967 func ArgServer(w http.ResponseWriter, req *http.Request) {
1967 for i, s := range os.Args { 1968 for i, s := range os.Args {
1968 fmt.Fprintln(c, s) 1969 fmt.Fprintln(w, s)
1969 } 1970 }
1970 } 1971 }
1971 </pre> 1972 </pre>
1972 <p> 1973 <p>
1973 <code>ArgServer</code> now has same signature as <code>HandlerFunc</code>, 1974 <code>ArgServer</code> now has same signature as <code>HandlerFunc</code>,
1974 so it can be converted to that type to access its methods, 1975 so it can be converted to that type to access its methods,
1975 just as we converted <code>Sequence</code> to <code>IntArray</code> 1976 just as we converted <code>Sequence</code> to <code>IntArray</code>
1976 to access <code>IntArray.Sort</code>. 1977 to access <code>IntArray.Sort</code>.
1977 The code to set it up is concise: 1978 The code to set it up is concise:
1978 </p> 1979 </p>
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 2796
2796 func main() { 2797 func main() {
2797 flag.Parse() 2798 flag.Parse()
2798 http.Handle("/", http.HandlerFunc(QR)) 2799 http.Handle("/", http.HandlerFunc(QR))
2799 err := http.ListenAndServe(*addr, nil) 2800 err := http.ListenAndServe(*addr, nil)
2800 if err != nil { 2801 if err != nil {
2801 log.Exit("ListenAndServe:", err) 2802 log.Exit("ListenAndServe:", err)
2802 } 2803 }
2803 } 2804 }
2804 2805
2805 func QR(c http.ResponseWriter, req *http.Request) { 2806 func QR(w http.ResponseWriter, req *http.Request) {
2806 templ.Execute(req.FormValue("s"), c) 2807 templ.Execute(req.FormValue("s"), w)
2807 } 2808 }
2808 2809
2809 func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) { 2810 func UrlHtmlFormatter(w io.Writer, v interface{}, fmt string) {
2810 template.HTMLEscape(w, []byte(http.URLEscape(v.(string)))) 2811 template.HTMLEscape(w, []byte(http.URLEscape(v.(string))))
2811 } 2812 }
2812 2813
2813 2814
2814 const templateStr = ` 2815 const templateStr = `
2815 &lt;html&gt; 2816 &lt;html&gt;
2816 &lt;head&gt; 2817 &lt;head&gt;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2889 <pre> 2890 <pre>
2890 verifying implementation 2891 verifying implementation
2891 type Color uint32 2892 type Color uint32
2892 ···· 2893 ····
2893 // Check that Color implements image.Color and image.Image 2894 // Check that Color implements image.Color and image.Image
2894 var _ image.Color = Black 2895 var _ image.Color = Black
2895 var _ image.Image = Black 2896 var _ image.Image = Black
2896 </pre> 2897 </pre>
2897 --> 2898 -->
2898 2899
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b