Golang 3
golanglogo.снимка
This time:
- Interfaces (for Rado with love)
- A simple server demonstration
- Bad jokes
Interfaces
Example:
package main
import "fmt"
type Shaper interface {
Area() int
}
type Rectangle struct {
length, width int
}
func (r Rectangle) Area() int {
return r.length * r.width
}
type Square struct {
side int
}
func (sq Square) Area() int {
return sq.side * sq.side
}
func main() {
r := Rectangle{length:5, width:3}
q := Square{side:5}
shapesArr := [...]Shaper{r, q}
fmt.Println("Looping through shapes for area ...")
for n, _ := range shapesArr {
fmt.Println("Shape details: ", shapesArr[n])
fmt.Println("Area of this shape is: ", shapesArr[n].Area())
}
}Let's look at some code
package main
import (
"fmt"
"net"
"os"
)
const (
CONN_HOST = "localhost"
CONN_PORT = "3333"
CONN_TYPE = "tcp"
)
func main() {
// Listen for incoming connections.
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// Handle connections in a new goroutine.
go handleRequest(conn)
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn) {
// Make a buffer to hold incoming data.
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
reqLen, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
// Send a response back to person contacting us.
conn.Write([]byte("Message received."))
// Close the connection when you're done with it.
conn.Close()
}Simple Caching
package main
import (
"bytes"
"io"
"log"
"net/http"
"os"
)
type fileCache struct {
buf bytes.Buffer
}
func (f *fileCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write(f.buf.Bytes())
}
var _ http.Handler = (*fileCache)(nil)
func NewCache(fileName string) *fileCache {
f, err := os.Open(fileName)
if err != nil {
log.Fatalf("couldn't open file: %v", err)
}
ret := &fileCache{}
_, err = io.Copy(&ret.buf, f)
if err != nil {
log.Fatalf("couldn't read file: %v", err)
}
return ret
}
func main() {
cache := NewCache("static.html")
http.Handle("/static.html", cache)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatalf("ListenAndServe error: %v", err)
}
}
and more code...
// Main file
func main() {
log.Printf("Starting webserver")
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))
setupHandlers()
if err := http.ListenAndServe("0.0.0.0:12345", nil); err != nil {
log.Fatal("ListenAndServe: ", context.ClearHandler(http.DefaultServeMux))
}
}
// Some other file
func setupHandlers() {
r := mux.NewRouter()
r.HandleFunc("/", makeHandler(homeHandle))
r.HandleFunc("/login", makeHandler(loginHandle))
r.HandleFunc("/logout", makeHandler(logoutHandle))
r.HandleFunc("/wallet", makeHandler(walletHandle))
r.HandleFunc("/wallet/{action}", makeHandler(walletActionHandle))
r.HandleFunc("/stash", makeHandler(stashHandle))
r.HandleFunc("/stash/{action}", makeHandler(stashActionHandle))
http.Handle("/", r)
}
func homeHandle(w http.ResponseWriter, r *http.Request, a *appRequest) {
if !a.isLoggedIn() {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
a.Data["flashes"] = a.Flashes()
a.Save(r, w)
executeDataTemplate(w, "home", a.Data)
}
func logoutHandle(w http.ResponseWriter, r *http.Request, a *appRequest) {
delete(a.Values, "login")
a.Save(r, w)
http.Redirect(w, r, "/", http.StatusFound)
}
Some interesting links:
https://www.hakkalabs.co/articles/optimizing-go-3k-requestssec-480k-requestssec
http://influxdb.com/
golang3
By Zlatin Stanimirov
golang3
- 1,007