Build-web-application-with-golang Learning Tutorials
In these weeks, learn the tutorials above and record only a few of the key points.
Go Language Basics
Go is a C-like compiled language, but it compiles very quickly. The language has a total of 25 key words:
break default func interface selectcase defer go map structchan else goto package switchconst fallthrough if range typecontinue for import return var
- var and const Reference 2.2Go language base variables and constants declarations
- The package and import have been in short contact.
- Func is used to define functions and methods
- return for returning from function
- Defer for similar destructors
- Go for concurrency
- Select for different types of communication
- Interface for defining interfaces, refer to section 2.6
- struct is used to define abstract data types, refer to section 2.5
- Break, case, continue, for, Fallthrough, else, if, switch, goto, default these reference 2.3 process introduction
- Chan for Channel Communications
- Type is used to declare a custom type
- Map for declaring map type data
- Range for reading slice, map, channel data
The Go Program is package
organized by a package <pkgName>
line that tells us which package the current file belongs to, and the package name main
tells us that it is a standalone package that generates an executable file after it is compiled. In addition to main
the package, other packages will eventually generate *.a
files (that is, package files) and put them in (in the $GOPATH/pkg/$GOOS_$GOARCH
case of Mac $GOPATH/pkg/darwin_amd64
).
Each go program that can run independently must contain one package main
, which main
must contain an entry function main
that has no parameters
, and there is no return value.
The concept of packages is similar to the package in Python, and they all have some special benefits: modularity (the ability to divide your program into multiple modules) and reusability (each module can be reused by other applications).
Go Language Key Difficulty interface
Simply put, interface is a combination of method signatures, and we define a set of behaviors for an object through interface.
PackageMainImport "FMT"typeHumanstruct{NamestringAgeintPhonestring}typeStudentstruct{Human//anonymous fieldSchoolstringLoanfloat32}typeEmployeestruct{Human//anonymous fieldCompanystringMoneyfloat32}//human Implementing the Sayhi methodfunc(H Human) Sayhi () {fmt. Printf ("Hi, I am%s You can call me on%s\ n", H.name, H.phone)}//human Implementing the Sing methodfunc(H Human) Sing (lyricsstring) {FMT. Println (" Los Angeles la ...", lyrics)}Sayhi method for//employee overloaded humanfunc(e Employee) Sayhi () {fmt. Printf (' Hi, I am%s, I work at%s. ' Call me ' on '%s '\ n", E.name, E.company, E.phone)}//Interface men are implemented by Human,student and employee//Because these three types implement both methodstypeMenInterface{Sayhi () Sing (lyricsstring)}funcMain () {Mike: = student{human{"Mike.", -,"222-222-xxx"},"MIT",0. XX} PAUL: = student{human{"Paul.", -,"111-222-xxx"},"Harvard", -} Sam: = employee{human{"Sam", $,"444-222-xxx"},"Golang Inc", +} Tom: = employee{human{"Tom",Panax Notoginseng,"222-444-xxx"},"Things Ltd.", the}//Define the type of men variable i varI men//i can store studenti = Mike Fmt. Println ("This is Mike, a Student:") I.sayhi () i.sing ("November Rain")//i can also store employeei = Tom Fmt. Println ("This was Tom, an Employee:") I.sayhi () i.sing ("Born to Be Wild")//define the slice menFmt. Println ("Let's use a slice of the men and see what happens") x: = Make([]men,3)//These three are different types of elements, but they implement the same interface as the interfacex[0], x[1], x[2] = Paul, Sam, Mike for_, Value: =Rangex{value. Sayhi ()}}
Interface is a set of abstract methods that must be implemented by other non-interface types and not self-fulfilling.
Empty interface
Empty interface (interface{}) does not contain any method, and because of this, all types implement an empty interface. The null interface does not have any effect on the description (because it does not contain any method), but the null interface is useful when we need to store any type of numeric value, because it can store any type of value. It is somewhat similar to the void* type of C language.
// 定义a为空接口varinterface{}varint5"Hello world"// a可以存储任意类型的数值a = ia = s
Goroutine
Goroutine is the core of go parallel design. Goroutine In fact is the association, but it is smaller than the thread, more than 10 goroutine may be reflected in the bottom is five or six threads, the go language inside to help you achieve the memory sharing between these goroutine. Execution goroutine requires very little stack memory (presumably 4~5kb) and will, of course, scale according to the corresponding data. Because of this, thousands of concurrent tasks can be run concurrently. Goroutine is easier to use, more efficient and lighter than thread.
Goroutine is a thread manager managed through the runtime of Go. Goroutine is implemented by the GO keyword, which is actually a normal function.
package main ( "FMT" "runtime" ) func say (s string ) {for I: = 0 ; i < 5 ; i++ {runtime. Gosched () fmt. Println (s)}}func main () {go Say () Span class= "CO" >//open a new Goroutines execute say ( "Hello" ) //current Goroutines execution }//: //Hello //World Span class= "Co" >//Hello //World //Hello // World //Hello //World //Hello
Channels
The goroutine runs in the same address space, so access to shared memory must be well synchronized. So how does data communicate between Goroutine, go provides a good communication mechanism channel. The channel can be analogous to a bidirectional pipeline in a Unix shell: it can send or receive values. These values can only be of a specific type: Channel type. When defining a channel, you also need to define the type of value sent to the channel. Note that you must use make to create the channel:
PackageMainImport "FMT"funcSum (A []intCChan int) {total: =0 for_, V: =RangeA {total + = v} C <-Total//Send total to C}funcMain () {a: = []int{7,2,8, -9,4,0} c: = Make(Chan int)GoSUM (a[:Len(a)/2], c)GoSUM (a[Len(a)/2:], c) x, y: = <-c, <-c//Receive from CFmt. Println (x, y, x + y)}
Web Service with Golanggo building a Web server
The web is a service based on the HTTP protocol, the Go language provides a complete net/http package, through the HTTP package can be very convenient to build up a running Web service. At the same time using this package can be very simple to the Web routing, static files, templates, cookies and other data set and operation.
PackageMainImport("FMT" "Net/http" "Strings" "Log")funcSayhelloname (w http. Responsewriter, R *http. Request) {r.parseform ()//parse parameter, default is not resolvedFmt. Println (R.form)//This information is output to the server-side printing informationFmt. Println ("Path", R.url. Path) fmt. Println ("scheme", R.url. Scheme) fmt. Println (r.form["Url_long"]) forK, V: =RangeR.form {fmt. Println ("key:", K) Fmt. Println ("val:", strings. Join (V,"")} FMT. fprintf (W,"Hello astaxie!")//This write to W is output to the client's}funcMain () {http. Handlefunc ("/", Sayhelloname)//Set access routesERR: = http. Listenandserve (": 9090",Nil)//Set the listening port ifErr! =Nil{log. Fatal ("Listenandserve:", err)}}
To see the above code, it is very simple to write a Web server, as long as the two functions of the HTTP packet are called (similar to Python's tornado). After we build, and then execute Web.exe, this time has actually been listening on the 9090 port HTTP link request.
In the browser inputhttp://localhost:9090
You can see the browser page outputHello astaxie!
You can try a different address:http://localhost:9090/?url_long=111&url_long=222
See what the browser output is, what is the server output?
Go's Web Service bottom
HTTP Package Execution Flow
Creates a listen Socket, listens on the specified port, waits for a client request to arrive.
The Listen socket accepts the client's request, obtains the customer socket, and then communicates with the client through the customer socket.
Processing the client's request, first read the HTTP request from the client socket protocol header, if it is the post method, you may also want to read the data submitted by the client, and then to the corresponding handler processing request, handler processing finished ready for the client to prepare the data, The client socket is addressed to clients.
In this whole process, we just need to know the following three questions and know how go makes the web work.
- How do I listen to ports?
- How do I receive client requests?
- How do I allocate handler?
In the code in the preceding section, we can see that go is handled by a function, which is ListenAndServe
actually handled by initializing a server object, then invoking net.Listen("tcp", addr)
, that is, the bottom layer uses the TCP protocol to build a service, and then monitors the ports we set up.
The following code from Go HTTP package source code, through the following code we can see the entire HTTP processing process:
func(SRV *server) Serve (l net. Listener)Error{deferL.close ()varTempdelay time. Duration//How long -to-sleep on accept failure for{RW, E: = L.accept ()ifE! =Nil{ifNE, OK: = E. (NET. ERROR); Ok && ne. Temporary () {ifTempdelay = =0{Tempdelay =5* Time.millisecond}Else{Tempdelay *=2}ifMax: =1* Time. Second; Tempdelay > Max {tempdelay = max} log. Printf ("Http:accept error:%v; Retrying in%v ", E, Tempdelay) time. Sleep (Tempdelay)Continue}returne} Tempdelay =0C, Err: = Srv.newconn (rw)ifErr! =Nil{Continue}GoC.serve ()}}
How do I receive client requests after monitoring? After the above code executes the monitoring port, the function is called, which srv.Serve(net.Listener)
is processing the request information of the receiving client. This function inside a for{}
, first through listener receive request, second create a conn, finally opened a goroutine, the request data as parameters throw to this conn to service: go c.serve()
. This is the high concurrency reflects that the user's every request is in a new goroutine to service, not affect each other.
So how do you assign the appropriate function to handle the request? Conn first parses the request: and c.readRequest()
then gets the corresponding handler: handler := c.server.Handler
that is, we just called the function ListenAndServe
when the second argument, we passed the previous example is nil, that is, empty, then the default gets handler = DefaultServeMux
, So what is this variable used for? Yes, this variable is a router, it is used to match the URL to jump to its corresponding handle function, then we have set it? Yes, the first sentence in the code we call is not called http.HandleFunc("/", sayhelloName)
. This function is to register the request /
routing rules, when the request URI is "/", the route will go to the function Sayhelloname,defaultservemux will call the Servehttp method, this method is actually called Sayhelloname itself , and finally by writing response feedback to the client.
The entire process is detailed as shown:
Execution flow of Go code
With the analysis of the HTTP packet, let's now comb through the entire code execution process.
First Call Http.handlefunc
In order to do a few things:
1 called the Handlefunc of Defaultservemux.
2 called the handle of Defaultservemux.
3 Add the corresponding handler and routing rules to the map[string]muxentry in Defaultservemux
Next, call HTTP. Listenandserve (": 9090", nil)
In order to do a few things:
1 instantiating the server
2 calling the server's Listenandserve ()
3 Call net. Listen ("tcp", addr) Listening port
4 Start A For loop, accept requests in the loop body
5 instantiate a conn for each request and open a Goroutine to service the request Go C.serve ()
6 read the contents of each request W, err: = C.readrequest ()
7 Determine if handler is empty, if not set handler (this example is not set handler), handler is set to Defaultservemux
8 Calling Handler's Servehttp
9 In this example, the following goes into the Defaultservemux.servehttp
10 Select handler according to request and enter into this handler servehttp
mux.handler(r).ServeHTTP(w, r)
11 Select handler:
A determine if there is a route to satisfy this request (looping through Servemux's muxentry)
B If there is a route to satisfy, call this route handler Servehttp
C If no route is met, call Notfoundhandler's servehttp
Form
Forms are commonly used to write Web applications, and through forms we can easily make the client and server interact with the data.
A form is a region that contains form elements. Form elements are elements that allow users to enter information in a table consignments (such as a text field, drop-down list, radio box, check box, and so on). Forms use Form labels (
Build-web-application-with-golang Study Notes