edu.anarcho-copy.org Languages/Go...1.1 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3 1.3.1 1.3.2 1.3.3...

327

Transcript of edu.anarcho-copy.org Languages/Go...1.1 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3 1.3.1 1.3.2 1.3.3...

  • 1.1

    1.2

    1.2.1

    1.2.2

    1.2.3

    1.2.4

    1.2.5

    1.3

    1.3.1

    1.3.2

    1.3.3

    1.3.4

    1.3.5

    1.3.6

    1.3.7

    1.3.8

    1.4

    1.4.1

    1.4.2

    1.4.3

    1.4.4

    1.4.5

    1.5

    1.5.1

    1.5.2

    1.5.3

    1.5.4

    1.5.5

    1.5.6

    1.6

    1.6.1

    1.6.2

    1.6.3

    1.6.4

    1.6.5

    1.6.6

    1.6.7

    1.7

    1.7.1

    TableofContentsIntroduction

    GoEnvironmentConfiguration

    Installation

    $GOPATHandworkspace

    Gocommands

    Godevelopmenttools

    Summary

    Gobasicknowledge

    Hello,Go

    Gofoundation

    Controlstatementsandfunctions

    struct

    Object-oriented

    interface

    Concurrency

    Summary

    Webfoundation

    Webworkingprinciples

    Buildasimplewebserver

    HowGoworkswithweb

    Getintohttppackage

    Summary

    HTTPForm

    Processforminputs

    Validationofinputs

    Crosssitescripting

    Duplicatesubmissions

    Fileupload

    Summary

    Database

    database/sqlinterface

    HowtouseMySQL

    HowtouseSQLite

    HowtousePostgreSQL

    HowtousebeedbORM

    NOSQL

    Summary

    Datastorageandsession

    Sessionandcookies

    2

  • 1.7.2

    1.7.3

    1.7.4

    1.7.5

    1.8

    1.8.1

    1.8.2

    1.8.3

    1.8.4

    1.8.5

    1.8.6

    1.8.7

    1.9

    1.9.1

    1.9.2

    1.9.3

    1.9.4

    1.9.5

    1.10

    1.10.1

    1.10.2

    1.10.3

    1.10.4

    1.10.5

    1.10.6

    1.10.7

    1.11

    1.11.1

    1.11.2

    1.11.3

    1.11.4

    1.12

    1.12.1

    1.12.2

    1.12.3

    1.12.4

    1.13

    1.13.1

    1.13.2

    1.13.3

    1.13.4

    1.13.5

    HowtousesessioninGo

    Sessionstorage

    Preventhijackofsession

    Summary

    Textfiles

    XML

    JSON

    Regexp

    Templates

    Files

    Strings

    Summary

    Webservices

    Sockets

    WebSocket

    REST

    RPC

    Summary

    Securityandencryption

    CSRFattacks

    Filterinputs

    XSSattacks

    SQLinjection

    Passwordstorage

    Encryptanddecryptdata

    Summary

    Internationalizationandlocalization

    Timezone

    Localizedresources

    Internationalsites

    Summary

    Errorhandling,debuggingandtesting

    Errorhandling

    DebuggingbyusingGDB

    Writetestcases

    Summary

    Deploymentandmaintenance

    Logs

    Errorsandcrashes

    Deployment

    Backupandrecovery

    Summary

    3

  • 1.14

    1.14.1

    1.14.2

    1.14.3

    1.14.4

    1.14.5

    1.14.6

    1.15

    1.15.1

    1.15.2

    1.15.3

    1.15.4

    1.15.5

    1.15.6

    1.15.7

    1.16

    1.17

    Buildawebframework

    Projectprogram

    Customizedrouters

    Designcontrollers

    Logsandconfigurations

    Add,deleteandupdateblogs

    Summary

    Developwebframework

    Staticfiles

    Session

    Form

    Uservalidation

    Multi-languagesupport

    pprof

    Summary

    References

    preface

    4

  • BuildWebApplicationwithGolangPurpose

    BecauseI'minterestedinwebapplicationdevelopment,Iusedmyfreetimetowritethisbookasanopensourceversion.Itdoesn'tmeanthatIhaveaverygoodabilitytobuildwebapplications;IwouldliketosharewhatI'vedonewithGoinbuildingwebapplications.

    ForthoseofyouwhoareworkingwithPHP/Python/Ruby,youwilllearnhowtobuildawebapplicationwithGo.ForthoseofyouwhoareworkingwithC/C++,youwillknowhowthewebworks.

    Ibelievethepurposeofstudyingissharingwithothers.ThehappiestthinginmylifeissharingeverythingI'veknownwithmorepeople.

    Donate

    AliPay:

    alipay

    EnglishDonate:donate

    CommunityQQ群:386056972

    BBS:http://gocn.io/

    Acknowledgments四月份平民AprilCitizen(reviewcode)洪瑞琦HongRuiqi(reviewcode)边疆BianJiang(writetheconfigurationsaboutVimandEmacsforGodevelopment)欧林猫OlingCat(reviewcode)吴文磊WenleiWu(providesomepictures)北极星Polaris(reviewwholebook)雨痕RainTrail(reviewchapter2and3)

    LicenseThisbookislicensedundertheCCBY-SA3.0License,thecodeislicensedunderaBSD3-ClauseLicense,unlessotherwisespecified.

    GetStarted

    Index

    Introduction

    5

    http://beego.me/donatehttp://gocn.io/https://plus.google.com/110445767383269817959https://github.com/hongruiqihttps://github.com/borderhttps://github.com/OlingCatmailto:[email protected]://github.com/polaris1119https://github.com/qyuhenhttp://creativecommons.org/licenses/by-sa/3.0/https://github.com/astaxie/build-web-application-with-golang/blob/master/LICENSE.md

  • Introduction

    6

  • 1GoEnvironmentConfigurationWelcometotheworldofGo,let'sstartexploring!

    Goisafast-compiled,garbage-collected,concurrentsystemsprogramminglanguage.Ithasthefollowingadvantages:

    Compilesalargeprojectwithinafewseconds.Providesasoftwaredevelopmentmodelthatiseasytoreasonabout,avoidingmostoftheproblemsassociatedwithC-styleheaderfiles.Isastaticlanguagethatdoesnothavelevelsinitstypesystem,sousersdonotneedtospendmuchtimedealingwithrelationsbetweentypes.Itismorelikealightweightobject-orientedlanguage.Performsgarbagecollection.Itprovidesbasicsupportforconcurrencyandcommunication.Designedformulti-corecomputers.

    Goisacompiledlanguage.Itcombinesthedevelopmentefficiencyofinterpretedordynamiclanguageswiththesecurityofstaticlanguages.Itisgoingtobethelanguageofchoiceformodern,multi-corecomputerswithnetworking.Forthesepurposes,therearesomeproblemsthatneedtoinherentlyberesolvedatthelevelofthelanguageofchoice,suchasarichlyexpressivelightweighttypesystem,anativeconcurrencymodel,andstrictlyregulatedgarbagecollection.Forquitesometime,nopackagesortoolshaveemergedthathaveaimedtosolvealloftheseproblemsinapragmaticfashion;thuswasbornthemotivationfortheGolanguage.

    Inthischapter,IwillshowyouhowtoinstallandconfigureyourownGodevelopmentenvironment.

    LinksDirectoryNextsection:Installation

    GoEnvironmentConfiguration

    7

  • 1.1Installation

    ThreewaystoinstallGoTherearemanywaystoconfiguretheGodevelopmentenvironmentonyourcomputer,andyoucanchoosewhicheveroneyoulike.Thethreemostcommonwaysareasfollows.

    Officialinstallationpackages.TheGoteamprovidesconvenientinstallationpackagesinWindows,Linux,Macandotheroperatingsystems.Thisisprobablytheeasiestwaytogetstarted.YoucangettheinstallersfromtheGolangDownloadPage.

    Installityourselffromsourcecode.PopularwithdeveloperswhoarefamiliarwithUnix-likesystems.

    Usingthird-partytools.Therearemanythird-partytoolsandpackagemanagersforinstallingGo,likeapt-getinUbuntuandhomebrewforMac.

    IncaseyouwanttoinstallmorethanoneversionofGoonacomputer,youshouldtakealookatatoolcalledGVM.ItisthebesttoolI'veseensofarforaccomplishingthistask,otherwiseyou'dhavetodealwithityourself.

    InstallfromsourcecodeTocompileGo1.5andupwards,youonlyneedthepreviousversionofGo,asGohasachievedbootstrapping.YouonlyneedGotocompileGo.

    TocompileGo1.4downwards,youwillneedaCcompilerassomepartsofGoarestillwritteninPlan9CandAT&Tassembler.

    OnaMac,ifyouhaveinstalledXcode,youalreadyhavethecompiler.

    OnUnix-likesystems,youneedtoinstallgccorasimilarcompiler.Forexample,usingthepackagemanagerapt-get(includedwithUbuntu),onecaninstalltherequiredcompilersasfollows:

    sudoapt-getinstallgcclibc6-dev

    OnWindows,youneedtoinstallMinGWinordertoinstallgcc.Don'tforgettoconfigureyourenvironmentvariablesaftertheinstallationhascompleted.(Everythingthatlookslikethismeansit'scommentedbyatranslator:Ifyouareusing64-bitWindows,youshouldinstallthe64-bitversionofMinGW)

    Atthispoint,executethefollowingcommandstoclonetheGosourcecodeandcompileit.(Itwillclonethesourcecodetoyourcurrentdirectory.Switchyourworkpathbeforeyoucontinue.Thismaytakesometime.)

    gitclonehttps://go.googlesource.com/gocdgo/src./all.bash

    Asuccessfulinstallationwillendwiththemessage"ALLTESTSPASSED."

    OnWindows,youcanachievethesamebyrunningall.bat.

    IfyouareusingWindows,theinstallationpackagewillsetyourenvironmentvariablesautomatically.InUnix-likesystems,youneedtosetthesevariablesmanuallyasfollows.(IfyourGoversionisgreaterthan1.0,youdon'thavetoset$GOBIN,anditwillautomaticallyberelatedtoyour$GOROOT/bin,whichwewilltalkaboutinthenextsection)

    Installation

    8

    https://golang.org/dl/https://github.com/moovweb/gvm

  • exportGOROOT=$HOME/goexportGOBIN=$GOROOT/binexportPATH=$PATH:$GOROOT/bin

    Ifyouseethefollowinginformationonyourscreen,you'reallset.

    Figure1.1Informationafterinstallingfromsourcecode

    OnceyouseetheusageinformationofGo,itmeansyouhavesuccessfullyinstalledGoonyourcomputer.Ifitsays"nosuchcommand",checkthatyour$PATHenvironmentvariablecontainstheinstallationpathofGo.

    UsingthestandardinstallationpackagesGohasone-clickinstallationpackagesforeverysupportedoperatingsystem.ThesepackageswillinstallGoin/usr/local/go(c:\GoinWindows)bydefault.Ofcoursethiscanbemodified,butyoualsoneedtochangealltheenvironmentvariablesmanuallyasI'veshownabove.

    Howtocheckifyouroperatingsystemis32-bitor64-bit?

    Ournextstepdependsonyouroperatingsystemtype,sowehavetocheckitbeforewedownloadthestandardinstallationpackages.

    IfyouareusingWindows,pressWin+Randthenrunthecommandtool.Typethesysteminfocommandanditwillshowyousomeusefulsysteminformation.Findthelinethatsays"systemtype"-ifyousee"x64-basedPC"thatmeansyouroperatingsystemis64-bit,32-bitotherwise.

    Istronglyrecommenddownloadingthe64-bitpackageifyouareaMacuser,asGonolongersupportspure32-bitprocessorsonMacOSX.

    Linuxuserscantypeuname-aintheterminaltoseesysteminformation.A64-bitoperatingsystemwillshowthefollowing:

    x86_64x86_64x86_64GNU/Linux//somemachinessuchasUbuntu10.04willshowasfollowingx86_64GNU/Linux

    32-bitoperatingsystemsinsteadshow:

    i686i686i386GNU/Linux

    Mac

    Gotothedownloadpage,choosego1.4.2.darwin-386.pkg(Thelaterversionhasno32-bitdownload.)for32-bitsystemsandgo1.8.3.darwin-amd64.pkgfor64-bitsystems.Goingallthewaytotheendbyclicking"next",~/go/binwillbeaddedtoyoursystem's$PATHafteryoufinishtheinstallation.Nowopentheterminalandtypego.Youshouldseethesameoutputshowninfigure1.1.

    Linux

    Gotothedownloadpage,choosego1.8.3.linux-386.tar.gzfor32-bitsystemsandgo1.8.3.linux-amd64.tar.gzfor64-bitsystems.SupposeyouwanttoinstallGointhe$GO_INSTALL_DIRpath.Uncompressthetar.gztoyourchosenpathusingthecommandtarzxvfgo1.8.3.linux-amd64.tar.gz-C$GO_INSTALL_DIR.Thensetyour$PATHwiththefollowing:exportPATH=$PATH:$GO_INSTALL_DIR/go/bin.Nowjustopentheterminalandtypego.Youshouldnowseethesameoutputdisplayedinfigure1.1.

    Installation

    9

    https://golang.org/dl/https://golang.org/dl/

  • Windows

    Gotothedownloadpage,choosego1.8.3.windows-386.msifor32-bitsystemsandgo1.8.3.windows-amd64.msifor64-bitsystems.Goingallthewaytotheendbyclicking"next",c:/go/binwillbeaddedtopath.Nowjustopenacommandlinewindowandtypego.Youshouldnowseethesameoutputdisplayedinfigure1.1.

    Usethird-partytools

    GVM

    GVMisaGomulti-versioncontroltooldevelopedbyathird-party,likervmforruby.It'squiteeasytouse.Installgvmbytypingthefollowingcommandsinyourterminal:

    bash<

  • 1. InstallGo

    brewupdate&&brewupgradebrewinstallgo

    LinksDirectoryPrevioussection:GoenvironmentconfigurationNextsection:$GOPATHandworkspace

    Installation

    11

  • 1.2$GOPATHandworkspace

    $GOPATHGotakesauniqueapproachtomanagethecodefileswiththeintroductionofa$GOPATHdirectorywhichcontainsallthegocodeinthemachine.Notethatthisisdifferentfromthe$GOROOTenvironmentvariablewhichstateswheregoisinstalledonthemachine.Wehavetodefinethe$GOPATHvariablebeforeusingthelanguage,in*nixsystemsthereisafilecalled.profileweneedtoappendthebelowexportstatementtothefile.Theconceptbehindgopathisanovelone,wherewecanlinktoanygocodeatanyinstantoftimewithoutambiguity.

    Startingfromgo1.8,theGOPATHenvironmentvariablenowhasadefaultvalueifitisunset.Itdefaultsto$HOME/goonUnixand%USERPROFILE%/goonWindows.

    InUnix-likesystems,thevariableshouldbeusedlikethis:

    exportGOPATH=${HOME}/mygo

    InWindows,youneedtocreateanewenvironmentvariablecalledGOPATH,thensetitsvaluetoc:\mygo(Thisvaluedependsonwhereyourworkspaceislocated)

    It'sOKtohavemorethanonepath(workspace)in$GOPATH,butrememberthatyouhavetouse:(;inWindows)tobreakthemup.Atthispoint,gogetwillsavethecontenttoyourfirstpathin$GOPATH.Itishighlyrecommendedtonothavemultiplesversions,theworstcaseistocreateafolderbythenameofyourprojectrightinside$GOPATH,itbreakseverythingthatthecreatorswerewishingtochangeinprogrammingwiththecreationofgolanguagebecausewhenyoucreateafolderinside$GOPATHyouwillreferenceyourpackagesasdirectlyas,andthisbreaksalltheapplicationswhichwillimportyourpackagebecausethegogetwon'tfindyourpackage.Pleasefollowconventions,thereisareasonconventionsarecreated.

    In$GOPATH,youmusthavethreefoldersasfollows:

    srcforsourcefileswhosesuffixis.go,.c,.g,.s.pkgforcompiledfileswhosesuffixis.a.binforexecutablefiles

    Inthisbook,Iusemygoasmyonlypathin$GOPATH.

    PackagedirectoryCreatepackagesourcefilesandfolderslike$GOPATH/src/mymath/sqrt.go(mymathisthepackagename)(Authorusesmymathashispackagename,andthesamenameforthefolderthatcontainsthepackagesourcefiles)

    Everytimeyoucreateapackage,youshouldcreateanewfolderinthesrcdirectory,withthenotableexceptionofmain,forwhichmainfoldercreationisoptional.Foldernamesareusuallythesameasthepackagethatyouaregoingtouse.Youcanhavemulti-leveldirectoriesifyouwantto.Forexample,ifyoucreatethedirectory$GOPATH/src/github.com/astaxie/beedb,thenthepackagepathwouldbegithub.com/astaxie/beedb.Thepackagenamewillbethelastdirectoryinyourpath,whichisbeedbinthiscase.

    Executefollowingcommands.(Nowauthorgoesbacktotalkexamples)

    cd$GOPATH/srcmkdirmymath

    Createanewfilecalledsqrt.go,typethefollowingcontenttoyourfile.

    $GOPATHandworkspace

    12

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

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

    Nowmypackagedirectoryhasbeencreatedandit'scodehasbeenwritten.Irecommendthatyouusethesamenameforyourpackagesastheircorrespondingdirectories,andthatthedirectoriescontainallofthepackagesourcefiles.

    CompilepackagesWe'vealreadycreatedourpackageabove,buthowdowecompileitforpracticalpurposes?Therearetwowaystodothis.

    1. Switchyourworkpathtothedirectoryofyourpackage,thenexecutethegoinstallcommand.2. Executetheabovecommandexceptwithafilename,likegoinstallmymath.

    Aftercompiling,wecanopenthefollowingfolder.

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

    Thefilewhosesuffixis.aisthebinaryfileofourpackage.Howdoweuseit?

    Obviously,weneedtocreateanewapplicationtouseit.

    Createanewapplicationpackagecalledmathapp.

    cd$GOPATH/srcmkdirmathappcdmathappvimmain.go

    Writethefollowingcontenttomain.go.

    //$GOPATH/src/mathapp/main.gosourcecode.packagemain

    import("mymath""fmt")

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

    Tocompilethisapplication,youneedtoswitchtotheapplicationdirectory,whichinthiscaseis$GOPATH/src/mathapp,thenexecutethegoinstallcommand.Nowyoushouldseeanexecutablefilecalledmathappwasgeneratedinthedirectory$GOPATH/bin/.Torunthisprogram,usethe./mathappcommand.Youshouldseethefollowingcontentinyourterminal.

    Helloworld.Sqrt(2)=1.414213562373095

    $GOPATHandworkspace

    13

  • InstallremotepackagesGohasatoolforinstallingremotepackages,whichisacommandcalledgoget.Itsupportsmostopensourcecommunities,includingGithub,GoogleCode,BitBucket,andLaunchpad.

    gogetgithub.com/astaxie/beedb

    Youcanusegoget-u…toupdateyourremotepackagesanditwillautomaticallyinstallallthedependentpackagesaswell.

    Thistoolwillusedifferentversioncontroltoolsfordifferentopensourceplatforms.Forexample,gitforGithubandhgforGoogleCode.Therefore,youhavetoinstalltheseversioncontroltoolsbeforeyouusegoget.

    Afterexecutingtheabovecommands,thedirectorystructureshouldlooklikefollowing.

    $GOPATHsrc|-github.com|-astaxie|-beedbpkg|--${GOOS}_${GOARCH}|-github.com|-astaxie|-beedb.a

    Actually,gogetclonessourcecodetothe$GOPATH/srcofthelocalfilesystem,thenexecutesgoinstall.

    Youcanuseremotepackagesinthesamewaythatweuselocalpackages.

    import"github.com/astaxie/beedb"

    DirectorycompletestructureIfyou'vefollowedalloftheabovesteps,yourdirectorystructureshouldnowlooklikethefollowing.

    bin/mathapppkg/${GOOS}_${GOARCH},suchasdarwin_amd64,linux_amd64mymath.agithub.com/astaxie/beedb.asrc/mathappmain.gomymath/sqrt.gogithub.com/astaxie/beedb/beedb.goutil.go

    Nowyouareabletoseethedirectorystructureclearly;bincontainsexecutablefiles,pkgcontainscompiledfilesandsrccontainspackagesourcefiles.

    (TheformatofenvironmentvariablesinWindowsis%GOPATH%,howeverthisbookmainlyfollowstheUnix-style,soWindowsusersneedtoreplacetheseyourself.)

    $GOPATHandworkspace

    14

  • LinksDirectoryPrevioussection:InstallationNextsection:Gocommands

    $GOPATHandworkspace

    15

  • 1.3Gocommands

    GocommandsTheGolanguagecomeswithacompletesetofcommandoperationtools.Youcanexecutethegocommandontheterminaltoseethem:

    Figure1.3Gocommanddisplaysdetailedinformation

    Theseareallusefulforus.Let'sseehowtousesomeofthem.

    gobuildThiscommandisforcompilingtests.Itwillcompilepackagesanddependenciesifit'snecessary.

    Ifthepackageisnotthemainpackagesuchasmymathinsection1.2,nothingwillbegeneratedafteryouexecutegobuild.Ifyouneedthepackagefile.ain$GOPATH/pkg,usegoinstallinstead.Ifthepackageisthemainpackage,itwillgenerateanexecutablefileinthesamefolder.Ifyouwantthefiletobegeneratedin$GOPATH/bin,usegoinstallorgobuild-o${PATH_HERE}/a.exe.Iftherearemanyfilesinthefolder,butyoujustwanttocompileoneofthem,youshouldappendthefilenameaftergobuild.Forexample,gobuilda.go.gobuildwillcompileallthefilesinthefolder.Youcanalsoassignthenameofthefilethatwillbegenerated.Forinstance,inthemathappproject(insection1.2),usinggobuild-oastaxie.exewillgenerateastaxie.exeinsteadofmathapp.exe.Thedefaultnameisyourfoldername(non-mainpackage)orthefirstsourcefilename(mainpackage).

    (AccordingtoTheGoProgrammingLanguageSpecification,packagenamesshouldbethenameafterthewordpackageinthefirstlineofyoursourcefiles.Itdoesn'thavetobethesameasthefoldername,andtheexecutablefilenamewillbeyourfoldernamebydefault.)

    gobuildignoresfileswhosenamesstartwith_or..Ifyouwanttohavedifferentsourcefilesforeveryoperatingsystem,youcannamefileswiththesystemnameasasuffix.Supposetherearesomesourcefilesforloadingarrays.Theycouldbenamedasfollows:

    array_linux.go|array_darwin.go|array_windows.go|array_freebsd.go

    gobuildchoosestheonethat'sassociatedwithyouroperatingsystem.Forexample,itonlycompilesarray_linux.goinLinuxsystems,andignoresalltheothers.

    gocleanThiscommandisforcleaningfilesthataregeneratedbycompilers,includingthefollowingfiles:

    _obj///olddirectoryofobject,leftbyMakefiles_test///olddirectoryoftest,leftbyMakefiles_testmain.go//olddirectoryofgotest,leftbyMakefilestest.out//olddirectoryoftest,leftbyMakefilesbuild.out//olddirectoryoftest,leftbyMakefiles*.[568ao]//objectfiles,leftbyMakefiles

    DIR(.exe)//generatedbygobuildDIR.test(.exe)//generatedbygotest-cMAINFILE(.exe)//generatedbygobuildMAINFILE.go

    Gocommands

    16

    https://golang.org/ref/spec

  • IusuallyusethiscommandtocleanupmyfilesbeforeIuploadmyprojecttoGithub.Theseareusefulforlocaltests,butuselessforversioncontrol.

    gofmtandgofmtThepeoplewhoareworkingwithC/C++shouldknowthatpeoplearealwaysarguingaboutwhichcodestyleisbetter:K&R-styleorANSI-style.HoweverinGo,thereisonlyonecodestylewhichisenforced.Forexample,leftbracesmustonlybeinsertedattheendoflines,andtheycannotbeontheirownlines,otherwiseyouwillgetcompileerrors!Fortunately,youdon'thavetoremembertheserules.gofmtdoesthisjobforyou.Justexecutethecommandgofmt.gointerminal.Idon'tusethiscommandverymuchbecauseIDEsusuallyexecutethiscommandautomaticallywhenyousavesourcefiles.IwilltalkmoreaboutIDEsinthenextsection.

    gofmtisjustanalias,whichrunsthecommand'gofmt-l-w'onthepackagesnamedbytheimportpaths.

    Weusuallyusegofmt-winsteadofgofmt.Thelatterwillnotrewriteyoursourcefilesafterformattingcode.gofmt-wsrcformatsthewholeproject.

    gogetThiscommandisforgettingremotepackages.Sofar,itsupportsBitBucket,Github,GoogleCodeandLaunchpad.Thereareactuallytwothingsthathappenafterweexecutethiscommand.ThefirstthingisthatGodownloadsthesourcecode,thenexecutesgoinstall.Beforeyouusethiscommand,makesureyouhaveinstalledalloftherelatedtools.

    BitBucket(MercurialGit)Github(git)GoogleCode(Git,Mercurial,Subversion)Launchpad(Bazaar)

    Inordertousethiscommand,youhavetoinstallthesetoolscorrectly.Don'tforgettoupdatethe$PATHvariable.Bytheway,italsosupportscustomizeddomainnames.Usegohelpimportpathformoredetailsaboutthis.

    goinstallThiscommandcompilesallpackagesandgeneratesfiles,thenmovesthemto$GOPATH/pkgor$GOPATH/bin.

    gotestThiscommandloadsallfileswhosenameinclude*_test.goandgeneratestestfiles,thenprintsinformationthatlookslikethefollowing.

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

    Ittestsallyourtestfilesbydefault.Usecommandgohelptestflagformoredetails.

    godocManypeoplesaythatwedon'tneedanythird-partydocumentationforprogramminginGo(actuallyI'vemadeaCHMalready).Gohasapowerfultooltomanagedocumentationnatively.

    Gocommands

    17

    https://github.com/astaxie/godoc

  • Sohowdowelookuppackageinformationindocumentation?Forinstance,ifyouwanttogetmoredetailsaboutthebuiltinpackage,usethegodocbuiltincommand.Similarly,usethegodocnet/httpcommandtolookupthehttppackagedocumentation.Ifyouwanttoseemoredetailsaboutspecificfunctions,usethegodocfmtPrintfandgodoc-srcfmtPrintfcommandstoviewthesourcecode.

    Executethegodoc-http=:8080command,thenopen127.0.0.1:8080inyourbrowser.Youshouldseealocalizedgolang.org.Itcannotonlyshowthestandardpackages'information,butalsopackagesinyour$GOPATH/pkg.It'sgreatforpeoplewhoaresufferingfromtheGreatFirewallofChina.

    OthercommandsGoprovidesmorecommandsthanthosewe'vejusttalkedabout.

    gofix//upgradecodefromanoldversionbeforego1toanewversionaftergo1goversion//getinformationaboutyourversionofGogoenv//viewenvironmentvariablesaboutGogolist//listallinstalledpackagesgorun//compiletemporaryfilesandruntheapplication

    TherearealsomoredetailsaboutthecommandsthatI'vetalkedabout.Youcanusegohelptolookthemup.

    LinksDirectoryPrevioussection:$GOPATHandworkspaceNextsection:Godevelopmenttools

    Gocommands

    18

  • GodevelopmenttoolsInthissection,I'mgoingtoshowyouafewIDEsthatcanhelpyoubecomeamoreefficientprogrammer,withcapabilitiessuchasintelligentcodecompletionandauto-formatting.Theyareallcross-platform,sothestepsIwillbeshowingyoushouldnotbeverydifferent,evenifyouarenotusingthesameoperatingsystem.

    LiteIDELiteIDEisanopensource,lightweightIDEfordevelopingGoprojectsonly,developedbyvisualfc.

    Figure1.4MainpanelofLiteIDE

    LiteIDEfeatures.

    Cross-platformWindowsLinuxMacOS

    Cross-compileManagemultiplecompileenvironmentsSupportscross-compilationofGo

    ProjectmanagementstandardDocumentationviewbasedon$GOPATHCompilationsystembasedon$GOPATHAPIdocumentationindexbasedon$GOPATH

    GosourcecodeeditorCodeoutliningFullsupportofgocodeGodocumentationviewandAPIindexViewcodeexpressionusingF1FunctiondeclarationjumpusingF2GdbsupportAuto-formatwithgofmt

    OthersMulti-languagePluginsystemTexteditorthemesSyntaxsupportbasedonKateintelligentcompletionbasedonfull-textCustomizedshortcutsMarkdownsupport

    Real-timepreviewCustomizedCSSExportHTMLandPDFConvertandmergetoHTMLandPDF

    LiteIDEinstallationInstallLiteIDE

    Downloadpage

    Godevelopmenttools

    19

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

  • Sourcecode

    YouneedtoinstallGofirst,thendownloadtheversionappropriateforyouroperatingsystem.Decompressthepackagetodirectlyuseit.

    Installgocode

    Youhavetoinstallgocodeinordertouseintelligentcompletion

    goget-ugithub.com/nsf/gocode

    Compilationenvironment

    SwitchconfigurationinLiteIDEtosuityouroperatingsystem.InWindowsandusingthe64-bitversionofGo,youshouldchoosewin64astheconfigurationenvironmentinthetoolbar.Then,chooseOptions,findLiteEnvintheleftlistandopenfilewin64.envintherightlist.

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

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

    ReplaceGOROOT=c:\gotoyourGoinstallationpath,saveit.IfyouhaveMinGW64,addc:\MinGW64\bintoyourpathenvironmentvariableforcgosupport.

    InLinuxandusingthe64-bitversionofGo,youshouldchooselinux64astheconfigurationenvironmentinthetoolbar.Then,chooseOptions,findLiteEnvintheleftlistandopenthelinux64.envfileintherightlist.

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

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

    ReplaceGOROOT=$HOME/gotoyourGoinstallationpath,saveit.

    $GOPATH$GOPATHisthepaththatcontainsalistofprojects.Openthecommandtool(orpressCtrl+`inLiteIDE),thentypegohelpgopathformoredetails.It'sveryeasytoviewandchange$GOPATHinLiteIDE.FollowView-SetupGOPATHtoviewandchangethesevalues.

    SublimeTextHereI'mgoingtointroduceyoutheSublimeText3(Sublimeforshort)+GoSublime+gocode.Letmeexplainwhy.

    Intelligentcompletion

    Figure1.5Sublimeintelligentcompletion

    Auto-formatsourcefilesProjectmanagement

    Godevelopmenttools

    20

    https://github.com/visualfc/liteide

  • Figure1.6Sublimeprojectmanagement

    Syntaxhighlight

    Freetrialforeverwithnofunctionallimitations.Youmaybepromptedonceinawhiletoremindyoutopurchasealicense,butyoucansimplyignoreitifyouwish.Ofcourse,ifyoudofindthatitenhancesyourproductivityandyoureallyenjoyusingit,pleasepurchaseacopyofitandsupportitscontinueddevelopment!

    First,downloadtheversionofSublimesuitableforyouroperatingsystem.

    1. PressCtrl+`,openthecommandtoolandinputthefollowingcommands.

    ApplicabletoSublimeText3:

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

    ApplicabletoSublimeText2:

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

    RestartSublimeTextwhentheinstallationhasfinished.Youshouldthenfinda`PackageControl`optioninthe"Preferences"menu.

    ![](images/1.4.sublime3.png?raw=true)

    Figure1.7SublimePackageControl

    1. ToinstallGoSublime,SidebarEnhancementsandGoBuild,pressCtrl+Shift+ptoopenPackageControl,thentypepcip(shortfor"PackageControl:InstallPackage").

    Figure1.8SublimeInstallPackages

    Nowtypein"GoSublime",pressOKtoinstallthepackage,andrepeatthesamestepsforinstallingSidebarEnhancementsandGoBuild.Onceagain,restarttheeditorwhenitcompletestheinstallation.

    2. Toverifythattheinstallationissuccessful,openSublime,thenopenthemain.gofiletoseeifithasthepropersyntaxhighlighting.Typeimporttoseeifcodecompletionpromptsappear.Aftertypingimport"fmt",typefmt.anywhereaftertheimportdeclarationtoseewhetherornotintelligentcodecompletionforfunctionswassuccessfullyenabled.

    Ifeverythingisfine,you'reallset.

    Ifnot,checkyour$PATHagain.Openaterminal,typegocode.Ifitdoesnotrun,your$PATHwasnotconfiguredcorrectly.

    VimVimisapopulartexteditorforprogrammers,whichevolvedfromitsslimmerpredecessor,Vi.Ithasfunctionsforintelligentcompletion,compilationandjumpingtoerrors.

    vim-goisvimaboveanopen-sourcegolanguageusingthemostextensivedevelopmentenvironmentplug-ins

    Thepluginaddress:github.com/fatih/vim-go

    Godevelopmenttools

    21

    http://www.sublimetext.com/https://github.com/fatih/vim-go

  • VimpluginmanagementarethemainstreamPathogenandVundle,Buttheaspectsthereofaredifferent.Pathogenistosolveeachplug-inaftertheinstallationoffilesscatteredtomultipledirectoriesandpoormanagementoftheexistence.Vundleistosolvetheautomaticsearchanddownloadplug-insexist.Thesetwoplug-inscanbeusedsimultaneously.

    1.InstallVundle

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

    Edit.vimrc,Vundletherelevantconfigurationwillbeplacedinthebeginning(RefertotheVundledocumentationfordetails)

    setnocompatible"beiMproved,requiredfiletypeoff"required

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

    "letVundlemanageVundle,requiredPlugin'gmarik/Vundle.vim'

    "AllofyourPluginsmustbeaddedbeforethefollowinglinecallvundle#end()"requiredfiletypepluginindenton"required

    2.InstallVim-go

    Edit~/.vimrc,Addalinebetweenvundle#beginandvundle#end:

    Plugin'fatih/vim-go'

    ExecutedwithinVim:PluginInstall

    3.InstallYCM(YourCompleteMe)toAutoCompleteAddalineto~/.vimrc:

    Plugin'Valloric/YouCompleteMe'

    ExecutedwithinVim:PluginInstall

    Figure1.8VimintelligentcompletionforGo

    1. SyntaxhighlightingforGo

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

    2. Enablingsyntaxhighlighting

    filetypepluginindentonsyntaxon

    3. Installgocode

    goget-ugithub.com/nsf/gocode

    gocodewillbeinstalledin$GOBINasdefault

    Godevelopmenttools

    22

    https://github.com/tpope/vim-pathogenhttps://github.com/VundleVim/Vundle.vimhttps://github.com/VundleVim/Vundle.vimhttps://github.com/nsf/gocode/

  • 4. Configuregocode

    ~cd$GOPATH/src/github.com/nsf/gocode/vim~./update.sh~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"

    Explanationofgocodeconfiguration:

    propose-builtins:specifieswhetherornottoopenintelligentcompletion;falsebydefault.lib-path:gocodeonlysearchesforpackagesin$GOPATH/pkg/$GOOS_$GOARCHand$GOROOT/pkg/$GOOS_$GOARCH.Thissettingcanbeusedtoaddadditionalpaths.

    5. Congratulations!Try:emain.gotoexperiencetheworldofGo!

    EmacsEmacsistheso-calledWeaponofGod.Sheisnotonlyaneditor,butalsoapowerfulIDE.

    Figure1.10EmacsmainpanelofGoeditor

    1. Syntaxhighlighting

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

    2. Installgocode

    goget-ugithub.com/nsf/gocode

    gocodewillbeinstalledin$GOBINasdefault

    3. Configuregocode

    ~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"

    4. InstallAutoCompletionDownloadanduncompress

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

    Configure~/.emacsfile

    Godevelopmenttools

    23

    https://github.com/nsf/gocode/https://github.com/nsf/gocode/https://github.com/nsf/gocode/http://www.emacswiki.org/emacs/AutoComplete

  • ;;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)

    Followthislinkformoredetails.

    5. Configure.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*")

    Godevelopmenttools

    24

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

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

    6. Congratulations,you'redone!Speedbarisclosedbydefault-removethecommentsymbolsintheline;;(speedbar1)toenablethisfeature,oryoucanuseitthroughM-xspeedbar.

    EclipseEclipseisalsoagreatdevelopmenttool.I'llshowyouhowtouseittowriteGoprograms.

    Figure1.1EclipsemainpanelforeditingGo

    1. DownloadandinstallEclipse2. Downloadgoclipsehttp://code.google.com/p/goclipse/wiki/InstallationInstructions3. Downloadgocode

    gocodeinGithub.

    https://github.com/nsf/gocode

    YouneedtoinstallgitinWindows,usuallyweusemsysgit

    Installgocodeinthecommandtool

    goget-ugithub.com/nsf/gocode

    Youcaninstallfromsourcecodeifyoulike.

    4. DownloadandinstallMinGW5. Configureplugins.

    Windows->Preferences->Go

    (1).ConfigureGocompiler

    Godevelopmenttools

    25

    http://www.eclipse.org/https://code.google.com/p/goclipse/http://code.google.com/p/goclipse/wiki/InstallationInstructionshttps://code.google.com/p/msysgit/http://sourceforge.net/projects/mingw/files/MinGW/

  • Figure1.12GoSettinginEclipse

    (2).Configuregocode(optional),setgocodepathtowherethegocode.exeis.

    Figure1.13gocodeSetting

    (3).Configuregdb(optional),setgdbpathtowherethegdb.exeis.

    Figure1.14gdbSetting

    6. Checktheinstallation

    CreateanewGoprojectandhello.gofileasfollowing.

    Figure1.15Createanewprojectandfile

    Testinstallationasfollows.(youneedtotypecommandinconsoleinEclipse)

    Figure1.16TestGoprograminEclipse

    IntelliJIDEAPeoplewhohaveworkedwithJavashouldbefamiliarwiththisIDE.ItsupportsGosyntaxhighlightingandintelligentcodecompletion,implementedbyaplugin.

    1. DownloadIDEA,thereisnodifferencebetweentheUltimateandCommunityeditions

    2. InstalltheGoplugin.ChooseFile-Setting-Plugins,thenclickBrowserrepo.

    3. Searchgolang,doubleclickdownloadandinstallandwaitforthedownloadtocomplete.

    ClickApply,thenrestart.

    4. NowyoucancreateaGoproject.

    InputthepositionofyourGosdkinthenextstep-basicallyit'syour$GOROOT.

    (SeeablogpostforsetupanduseIntelliJIDEAwithGostepbystep)

    VisualStudioVSCodeThisisanawesometexteditorreleasedasopensourcecrossplatformmyMicrosoftwhichtakesthedevelopmentexperiencetoawholenewlevel,https://code.visualstudio.com/.Ithaseverythingamoderntexteditorisexpectedtohaveanddespitebeingbasedonthesamebackendthatatom.ioisbased,itisveryfast.

    ItworkswithWindows,Mac,Linux.Ithasgopackagebuilt,itprovidescodelinting.

    Godevelopmenttools

    26

    http://wuwen.org/tips-about-using-intellij-idea-and-go/https://code.visualstudio.com/

  • AtomAtomisanawesometexteditorreleasedasopensourcecrossplatform,builtonElectron,andbasedoneverythingweloveaboutourfavoriteeditors.Wedesignedittobedeeplycustomizable,butstillapproachableusingthedefaultconfiguration.

    Download:https://atom.io/

    GoglandGoglandisthecodenameforanewcommercialIDEbyJetBrainsaimedatprovidinganergonomicenvironmentforGodevelopment.

    Theofficialversionisnotyetreleased。

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

    LinksDirectoryPrevioussection:GocommandsNextsection:Summary

    Godevelopmenttools

    27

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

  • 1.5SummaryInthischapter,wetalkedabouthowtoinstallGousingthreedifferentmethodsincludingfromsourcecode,thestandardpackageandviathird-partytools.ThenweshowedyouhowtoconfiguretheGodevelopmentenvironment,mainlycoveringhowtosetupyour$GOPATH.Afterthat,weintroducedsomestepsforcompilinganddeployingGoprograms.WethencoveredGocommands,includingthecompile,install,formatandtestcommands.Finally,therearemanypowerfultoolstodevelopGoprogramssuchasLiteIDE,SublimeText,VSCode,Atom,Goglang,Vim,Emacs,Eclipse,IntelliJIDEA,etc.YoucanchooseanyoneyoulikeexploringtheworldofGo.

    LinksDirectoryPrevioussection:GodevelopmenttoolsNextchapter:Gobasicknowledge

    Summary

    28

  • 2GobasicknowledgeGoisacompiledsystemprogramminglanguage,anditbelongstotheC-family.However,itscompilationspeedismuchfasterthanotherC-familylanguages.Ithasonly25keywords...evenlessthanthe26lettersoftheEnglishalphabet!Let'stakealookatthesekeywordsbeforewegetstarted.

    breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypecontinueforimportreturnvar

    Inthischapter,I'mgoingtoteachyousomebasicGoknowledge.YouwillfindouthowconcisetheGoprogramminglanguageis,andthebeautifuldesignofthelanguage.ProgrammingcanbeveryfuninGo.Afterwecompletethischapter,you'llbefamiliarwiththeabovekeywords.

    LinksDirectoryPreviouschapter:Chapter1SummaryNextsection:"Hello,Go"

    Gobasicknowledge

    29

  • WhatmakesGodifferentfromotherlanguages?TheGoprogramminglanguagewascreatedwithonegoalinmind,tobeabletobuildscalableweb-applicationsforlargescaleaudiencesinalargeteam.Sothatisthereasontheymadethelanguageasstandardizedaspossible,hencethegofmttoolandthestrictusageguidelinestothelanguagewasforthesakeofnothavingtwofactionsinthedeveloperbase,inotherlanguagestherearereligiouswarsonwheretokeeptheopeningbrace?

    publicstaticvoidmain(){

    }

    orpublicstaticvoidmain(){

    }

    orforpythonshouldweuse4spacesor6spacesoratabortwotabsandotheruserpreferences.IfyouknowpythonthenyoumightbeawareofPEP8,whichisasetofguidelinesabouthowtowriteelegantcode.

    Whilethismightseemtobeashallowproblem,whenthecodebasegrowsandmoreandmorepeopleworkonthesamecodebaseitisbecomesincreasinglydifficulttomaintainthecode's"beauty."Weliveinaworldwhererobotscandriveacar,soweshouldn'tjustwritecode,weshouldwriteelegantcode.

    Forotherlanguagestherearemanyvariableswhenitcomestowritingcode.Everylanguageisgoodforitsusecase,butGoisalittlespecialbecauseitwasdesignedatacompanywhichistheverysynonymoftheInternet(anddistributedcomputing).Typicallyinordertooptimizeprograms,developerschoosetowriteJavaoverPythonandC++overJava,butalmostallavailablelanguageswidelyinusewerewrittendecadesagowhen1GBstoragewasmuchpricier.Nowstorageandcomputingisrelativelycheapandcomputersaregettingmultiplescores,butthe"oldlanguages"arenotharnessingconcurrencyinawaythatgodoes.It'snotbecausethoselanguagesarebad;utilizingconcurrencywasn'tarelevantusecasewhiletheolderlanguagesevolved.

    TomitigatealltheproblemsthatGooglefacedwithcurrenttools,theywroteasystemslanguagecalledGowhichyouareabouttolearn!Therearemanyadvantagestousinggolangandtherearedisadvantagestoo,foreverycoinhasbothsides.Oneofthesignificantimprovementsinincodeformatting.Googlehasdesignedthelanguagetoavoiddebatesoncodeformatting.Gocodewrittenbyanyoneintheworld(assumingtheyknowandusegofmt)willlookexactlythesame.Thiswon'tseemtomatteruntilyouworkinateam!Alsowhenthecompanyusesautomatedcoderevieworsomeotherfancytechnique,theformattedcodemaybreakinotherlanguageswhichdon'thavestrictandstandardformattingrules,butnotingo!

    Gowasdesignedwithconcurrencyinmind,pleasenotethatparallelism!=concurrency,thereisanamazingpostbyRobPikeonthegolangblog,youwillfinditthere,itiswortharead.

    AnotherveryimportantchangethatistheconceptofGOPATH.Gonearethedayswhenyouhadtocreateafoldercalledcodeandthencreateworkspacesforeclipseandwhatnot.Nowyouhavetokeeponefoldertreeforgocodewhichwillbeupdatedbythepackagemanagerautomatically.Itisalsorecommendedtocreatefolderswitheitheracustomdomainorthegithubdomain,forexampleIcreatedataskmanagerusinggolangsoIcreatedasetoffolders~/go/src/github.com/thewhitetulip/Tasks

    Note:In*nixsystems~standsforhomedirectory,whichisthewindowsequivalentofC:\\Users\\username.Nowthe~/go/istheuniverseforthegocodeinyourmachine.Thisisasignificantimprovementoverotherlanguages;wecanstorethecodeefficientlywithouthassles.Whileitmightseemstrangeatfirst,thisapproachmakealotofsensethantheridiculouspackagenames,i.e.packagenamesgeneratedforotherlanguagesusingreversedomains.

    Note:Alongwithsrctherearetwofolderspkgwhichisforpackagesandbinwhichisforbinary.

    Hello,Go

    30

    https://blog.golang.org/concurrency-is-not-parallelismhttps://blog.golang.org/

  • ThisGOPATHadvantageisn'tjustrestrictedtostoringcodeinparticularfolder.Whenyouhavecreatedfivepackagesforyourproject,youdon'thavetoimportthemlike"import./db".Insteadyoucanuseimport"github.com/thewhitetulip/Tasks/db"sothatwhenexecutinggogetonmyrepo,thegotoolwillfindthepackagefromgithub.com/...pathifitwasn'tdownloadedinitially.Thisstandardizesalotofscrewedupthingsintheprogrammingdiscipline.(

  • Onthefifthline,weusethekeywordfunctodefinethemainfunction.Thebodyofthefunctionisinsideof{},justlikeC,C++andJava.

    Asyoucansee,therearenoarguments.Wewilllearnhowtowritefunctionswithargumentsinjustasecond,andyoucanalsohavefunctionsthathavenoreturnvalueorhaveseveralreturnvalues.

    Onthesixthline,wecalledthefunctionPrintfwhichisfromthepackagefmt.Thiswascalledbythesyntax.,whichisverylikePython-style.

    Aswementionedinchapter1,thepackage'snameandthenameofthefolderthatcontainsthatpackagecanbedifferent.Herethecomesfromthenameinpackage,notthefolder'sname.

    Youmaynoticethattheexampleabovecontainsmanynon-ASCIIcharacters.ThepurposeofshowingthisistotellyouthatGosupportsUTF-8bydefault.YoucanuseanyUTF-8characterinyourprograms.

    Eachgofileisinsomepackage,andthatpackageshouldbeadistinctfolderintheGOPATH,butmainisaspecialpackagewhichdoesn'trequireamainfolder.Thisisoneaspectwhichtheyleftoutforstandardization!Butshouldyouchoosetomakeamainfolderthenyouhavetoensurethatyourunthebinaryproperly.Alsoonegocodecan'thavemorethanonemaingofile.

    ~/go/src/github.com/thewhitetulip/Tasks/main$gobuild~/go/src/github.com/thewhitetulip/Tasks$./main/main

    thethinghereisthatwhenyourcodeisusingsomestaticfilesorsomethingelse,thenyououghttorunthebinaryfromtherootoftheapplicationasweseeinthesecondlineabove,Iamrunningthemainbinaryoutsidethemainpackage,sometimesyoumightwonderwhyyourapplicationisn'tworkingthenthismightbeoneofthepossibleproblems,pleasekeepthisinmind.

    Onethingyouwillnoticehereisthatgodoesn'tseetousesemicolonstoendastatement,well,itdoes,justthereisaminorcatch,theprogrammerisn'texpectedtoputsemicolons,thecompileraddssemicolonstothegocodewhenitcompileswhichisthereasonthatthis(thankfully!)isasyntaxerror

    funcmain(){}

    becausethecompileraddsasemicolonattheendofmain()whichisasyntaxerrorandasstatedabove,ithelpsavoidreligiouswars,iwishtheycombinevimandemacsandcreateauniversaleditorwhich'llhelpsavesomemorewars!Butfornowwe'lllearnGo.

    ConclusionGousespackage(likemodulesinPython)toorganizeprograms.Thefunctionmain.main()(thisfunctionmustbeinthemainpackage)istheentrypointofanyprogram.Gostandardizeslanguageandmostoftheprogrammingmethodology,savingtimeofdeveloperswhichthey'dhavewastedinreligiouswars.Therecanbeonlyonemainpackageandonlyonemainfunctioninsideagomainpackage.GosupportsUTF-8charactersbecauseoneofthecreatorsofGoisacreatorofUTF-8,soGohassupportedmultiplelanguagesfromthetimeitwasborn.

    LinksDirectoryPrevioussection:GobasicknowledgeNextsection:Gofoundation

    Hello,Go

    32

  • Hello,Go

    33

  • 2.2GofoundationInthissection,wearegoingtoteachyouhowtodefineconstants,variableswithelementarytypesandsomeskillsinGoprogramming.

    DefinevariablesTherearemanyformsofsyntaxthatcanbeusedtodefinevariablesinGo.

    Thekeywordvaristhebasicformtodefinevariables,noticethatGoputsthevariabletypeafterthevariablename.

    //defineavariablewithname“variableName”andtype"type"varvariableNametype

    Definemultiplevariables.

    //definethreevariableswhichtypesare"type"varvname1,vname2,vname3type

    Defineavariablewithinitialvalue.

    //defineavariablewithname“variableName”,type"type"andvalue"value"varvariableNametype=value

    Definemultiplevariableswithinitialvalues.

    /*Definethreevariableswithtype"type",andinitializetheirvalues.vname1isv1,vname2isv2,vname3isv3*/varvname1,vname2,vname3type=v1,v2,v3

    Doyouthinkthatit'stootedioustodefinevariablesusethewayabove?Don'tworry,becausetheGoteamhasalsofoundthistobeaproblem.Thereforeifyouwanttodefinevariableswithinitialvalues,wecanjustomitthevariabletype,sothecodewilllooklikethisinstead:

    /*Definethreevariableswithouttype"type",andinitializetheirvalues.vname1isv1,vname2isv2,vname3isv3*/varvname1,vname2,vname3=v1,v2,v3

    Well,Iknowthisisstillnotsimpleenoughforyou.Let'sseehowwefixit.

    /*Definethreevariableswithouttype"type"andwithoutkeyword"var",andinitializetheirvalues.vname1isv1,vname2isv2,vname3isv3*/vname1,vname2,vname3:=v1,v2,v3

    Nowitlooksmuchbetter.Use:=toreplacevarandtype,thisiscalledashortassignment.Ithasonelimitation:thisformcanonlybeusedinsideofafunctions.Youwillgetcompileerrorsifyoutrytouseitoutsideoffunctionbodies.Therefore,weusuallyusevartodefineglobalvariables.

    Gofoundation

    34

  • _(blank)isaspecialvariablename.Anyvaluethatisgiventoitwillbeignored.Forexample,wegive35tob,anddiscard34.(Thisexamplejustshowyouhowitworks.Itlooksuselessherebecauseweoftenusethissymbolwhenwegetfunctionreturnvalues.)

    _,b:=34,35

    Ifyoudon'tusevariablesthatyou'vedefinedinyourprogram,thecompilerwillgiveyoucompilationerrors.Trytocompilethefollowingcodeandseewhathappens.

    packagemain

    funcmain(){variint}

    ConstantsSo-calledconstantsarethevaluesthataredeterminedduringcompiletimeandyoucannotchangethemduringruntime.InGo,youcanusenumber,booleanorstringastypesofconstants.

    Defineconstantsasfollows.

    constconstantName=value//youcanassigntypeofconstantsifit'snecessaryconstPifloat32=3.1415926

    Moreexamples.

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

    Elementarytypes

    Boolean

    InGo,weusebooltodefineavariableasbooleantype,thevaluecanonlybetrueorfalse,andfalsewillbethedefaultvalue.(Youcannotconvertvariables'typebetweennumberandboolean!)

    //samplecodevarisActivebool//globalvariablevarenabled,disabled=true,false//omittypeofvariables

    functest(){varavailablebool//localvariablevalid:=false//briefstatementofvariableavailable=true//assignvaluetovariable}

    Numericaltypes

    Integertypesincludebothsignedandunsignedintegertypes.Gohasintanduintatthesametime,theyhavesamelength,butspecificlengthdependsonyouroperatingsystem.Theyuse32-bitin32-bitoperatingsystems,and64-bitin64-bitoperatingsystems.Goalsohastypesthathavespecificlengthincludingrune,int8,int16,int32,int64,byte,uint8,uint16,uint32,uint64.Notethatruneisaliasofint32andbyteisaliasofuint8.

    Gofoundation

    35

  • Oneimportantthingyoushouldknowthatyoucannotassignvaluesbetweenthesetypes,thisoperationwillcausecompileerrors.

    varaint8

    varbint32

    c:=a+b

    Althoughint32hasalongerlengththanint8,andhasthesametypeasint,youcannotassignvaluesbetweenthem.(cwillbeassertedastypeinthere)

    Floattypeshavethefloat32andfloat64typesandnotypecalledfloat.Thelatteroneisthedefaulttypeifusingbriefstatement.

    That'sall?No!Gosupportscomplexnumbersaswell.complex128(witha64-bitrealand64-bitimaginarypart)isthedefaulttype,ifyouneedasmallertype,thereisonecalledcomplex64(witha32-bitrealand32-bitimaginarypart).ItsformisRE+IMi,whereREisrealpartandIMisimaginarypart,thelastiistheimaginarynumber.Thereisaexampleofcomplexnumber.

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

    String

    WejusttalkedabouthowGousestheUTF-8characterset.Stringsarerepresentedbydoublequotes""orbackticks ̀ `.

    //samplecodevarfrenchHellostring//basicformtodefinestringvaremptyStringstring=""//defineastringwithemptystringfunctest(){no,yes,maybe:="no","yes","maybe"//briefstatementjapaneseHello:="Ohaiou"frenchHello="Bonjour"//basicformofassignvalues}

    It'simpossibletochangestringvaluesbyindex.Youwillgeterrorswhenyoucompilethefollowingcode.

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

    WhatifIreallywanttochangejustonecharacterinastring?Trythefollowingcode.

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

    Youusethe+operatortocombinetwostrings.

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

    andalso.

    Gofoundation

    36

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

    WhatifIwanttohaveamultiple-linestring?

    m:=`helloworld`

    ̀ willnotescapeanycharactersinastring.

    ErrortypesGohasoneerrortypeforpurposeofdealingwitherrormessages.Thereisalsoapackagecallederrorstohandleerrors.

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

    Underlyingdatastructure

    ThefollowingpicturecomesfromanarticleaboutGodatastructureinRussCox'sBlog.Asyoucansee,Goutilizesblocksofmemorytostoredata.

    Figure2.1Gounderlyingdatastructure

    Someskills

    Definebygroup

    Ifyouwanttodefinemultipleconstants,variablesorimportpackages,youcanusethegroupform.

    Basicform.

    import"fmt"import"os"

    consti=100constpi=3.1415constprefix="Go_"

    variintvarpifloat32varprefixstring

    Groupform.

    Gofoundation

    37

    http://research.swtch.com/godatahttp://research.swtch.com/

  • import("fmt""os")

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

    var(iintpifloat32prefixstring)

    Unlessyouassignthevalueofconstantisiota,thefirstvalueofconstantinthegroupconst()willbe0.Iffollowingconstantsdon'tassignvaluesexplicitly,theirvalueswillbethesameasthelastone.Ifthevalueoflastconstantisiota,thevaluesoffollowingconstantswhicharenotassignedareiotaalso.

    iotaenumerate

    Gohasonekeywordcallediota,thiskeywordistomakeenum,itbeginswith0,increasedby1.

    const(x=iota//x==0y=iota//y==1z=iota//z==2w//Ifthereisnoexpressionaftertheconstantsname,itusesthelastexpression,//soit'ssayingw=iotaimplicitly.Thereforew==3,andyandzbothcanomit"=iota"aswell.)

    constv=iota//onceiotameetskeyword`const`,itresetsto`0`,sov=0.

    const(e,f,g=iota,iota,iota//e=0,f=0,g=0valuesofiotaaresameinoneline.)

    Somerules

    ThereasonthatGoisconcisebecauseithassomedefaultbehaviors.

    Anyvariablethatbeginswithacapitallettermeansitwillbeexported,privateotherwise.Thesameruleappliesforfunctionsandconstants,nopublicorprivatekeywordexistsinGo.

    array,slice,map

    array

    arrayisanarrayobviously,wedefineoneasfollows.

    vararr[n]type

    in[n]type,nisthelengthofthearray,typeisthetypeofitselements.Likeotherlanguages,weuse[]togetorsetelementvalueswithinarrays.

    Gofoundation

    38

  • vararr[10]int//anarrayoftype[10]intarr[0]=42//arrayis0-basedarr[1]=13//assignvaluetoelementfmt.Printf("Thefirstelementis%d\n",arr[0])//getelementvalue,itreturns42fmt.Printf("Thelastelementis%d\n",arr[9])//itreturnsdefaultvalueof10thelementinthisarray,whichis0inthiscase.

    Becauselengthisapartofthearraytype,[3]intand[4]intaredifferenttypes,sowecannotchangethelengthofarrays.Whenyouusearraysasarguments,functionsgettheircopiesinsteadofreferences!Ifyouwanttousereferences,youmaywanttouseslice.We'lltalkaboutlater.

    It'spossibletouse:=whenyoudefinearrays.

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

    b:=[10]int{1,2,3}//defineaintarraywith10elements,ofwhichthefirstthreeareassigned.//Therestofthemusethedefaultvalue0.

    c:=[...]int{4,5,6}//use`…`toreplacethelengthparameterandGowillcalculateitforyou.

    Youmaywanttousearraysasarrays'elements.Let'sseehowtodothis.

    //defineatwo-dimensionalarraywith2elements,andeachelementhas4elements.doubleArray:=[2][4]int{[4]int{1,2,3,4},[4]int{5,6,7,8}}

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

    Arrayunderlyingdatastructure.

    Figure2.2Multidimensionalarraymappingrelationship

    sliceInmanysituations,thearraytypeisnotagoodchoice-forinstancewhenwedon'tknowhowlongthearraywillbewhenwedefineit.Thus,weneeda"dynamicarray".ThisiscalledsliceinGo.

    sliceisnotreallyadynamicarray.It'sareferencetype.slicepointstoanunderlyingarraywhosedeclarationissimilartoarray,butdoesn'tneedlength.

    //justlikedefininganarray,butthistime,weexcludethelength.varfslice[]int

    Thenwedefineaslice,andinitializeitsdata.

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

    slicecanredefineexistingslicesorarrays.sliceusesarray[i:j]toslice,whereiisthestartindexandjisendindex,butnoticethatarray[j]willnotbeslicedsincethelengthofthesliceisj-i.

    Gofoundation

    39

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

    //definetwosliceswithtype[]bytevara,b[]byte

    //'a'pointstoelementsfrom3rdto5thinarrayar.a=ar[2:5]//now'a'haselementsar[2],ar[3]andar[4]

    //'b'isanothersliceofarrayarb=ar[3:5]//now'b'haselementsar[3]andar[4]

    Noticethedifferencesbetweensliceandarraywhenyoudefinethem.Weuse[…]toletGocalculatelengthbutuse[]todefinesliceonly.

    Theirunderlyingdatastructure.

    Figure2.3Correspondencebetweensliceandarray

    slicehassomeconvenientoperations.

    sliceis0-based,ar[:n]equalstoar[0:n]Thesecondindexwillbethelengthofsliceifomitted,ar[n:]equalstoar[n:len(ar)].Youcanusear[:]toslicewholearray,reasonsareexplainedinfirsttwostatements.

    Moreexamplespertainingtoslice

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

    //someconvenientoperationsaSlice=array[:3]//equalstoaSlice=array[0:3]aSlicehaselementsa,b,caSlice=array[5:]//equalstoaSlice=array[5:10]aSlicehaselementsf,g,h,i,jaSlice=array[:]//equalstoaSlice=array[0:10]aSlicehasallelements

    //slicefromsliceaSlice=array[3:7]//aSlicehaselementsd,e,f,g,len=4,cap=7bSlice=aSlice[1:3]//bSlicecontainsaSlice[1],aSlice[2],soithaselementse,fbSlice=aSlice[:3]//bSlicecontainsaSlice[0],aSlice[1],aSlice[2],soithasd,e,fbSlice=aSlice[0:5]//slicecouldbeexpandedinrangeofcap,nowbSlicecontainsd,e,f,g,hbSlice=aSlice[:]//bSlicehassameelementsasaSlicedoes,whichared,e,f,g

    sliceisareferencetype,soanychangeswillaffectothervariablespointingtothesamesliceorarray.Forinstance,inthecaseofaSliceandbSliceabove,ifyouchangethevalueofanelementinaSlice,bSlicewillbechangedaswell.

    sliceislikeastructbydefinitionanditcontains3parts.

    Apointerthatpointstowhereslicestarts.Thelengthofslice.Capacity,thelengthfromstartindextoendindexofslice.

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

    Theunderlyingdatastructureofthecodeaboveasfollows.

    Gofoundation

    40

  • Figure2.4Arrayinformationofslice

    Therearesomebuilt-infunctionsforslice.

    lengetsthelengthofslice.capgetsthemaximumlengthofsliceappendappendsoneormoreelementstoslice,andreturnsslice.copycopieselementsfromoneslicetotheother,andreturnsthenumberofelementsthatwerecopied.

    Attention:appendwillchangethearraythatslicepointsto,andaffectotherslicesthatpointtothesamearray.Also,ifthereisnotenoughlengthfortheslice((cap-len)==0),appendreturnsanewarrayforthisslice.Whenthishappens,otherslicespointingtotheoldarraywillnotbeaffected.

    map

    mapbehaveslikeadictionaryinPython.Usetheformmap[keyType]valueTypetodefineit.

    Let'sseesomecode.The'set'and'get'valuesinmaparesimilartoslice,howevertheindexinslicecanonlybeoftype'int'whilemapcanusemuchmorethanthat:forexampleint,string,orwhateveryouwant.Also,theyareallabletouse==and!=tocomparevalues.

    //usestringasthekeytype,intasthevaluetype,and`make`initializeit.varnumbersmap[string]int//anotherwaytodefinemapnumbers:=make(map[string]int)numbers["one"]=1//assignvaluebykeynumbers["ten"]=10numbers["three"]=3

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

    Somenoteswhenyouusemap.

    mapisdisorderly.Everytimeyouprintmapyouwillgetdifferentresults.It'simpossibletogetvaluesbyindex-youhavetousekey.mapdoesn'thaveafixedlength.It'sareferencetypejustlikeslice.lenworksformapalso.Itreturnshowmanykeysthatmaphas.It'squiteeasytochangethevaluethroughmap.Simplyusenumbers["one"]=11tochangethevalueofkeyoneto11.

    Youcanuseformkey:valtoinitializemap'svalues,andmaphasbuilt-inmethodstocheckifthekeyexists.

    Usedeletetodeleteanelementinmap.

    //Initializeamaprating:=map[string]float32{"C":5,"Go":4.5,"Python":4.5,"C++":2}//maphastworeturnvalues.Forthesecondreturnvalue,ifthekeydoesn't//exist,'ok'returnsfalse.Itreturnstrueotherwise.csharpRating,ok:=rating["C#"]ifok{fmt.Println("C#isinthemapanditsratingis",csharpRating)}else{fmt.Println("WehavenoratingassociatedwithC#inthemap")}

    delete(rating,"C")//deleteelementwithkey"c"

    AsIsaidabove,mapisareferencetype.Iftwomapspointtosameunderlyingdata,anychangewillaffectbothofthem.

    Gofoundation

    41

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

    make,newmakedoesmemoryallocationforbuilt-inmodels,suchasmap,slice,andchannel,whilenewisfortypes'memoryallocation.

    new(T)allocateszero-valuetotypeT'smemory,returnsitsmemoryaddress,whichisthevalueoftype*T.ByGo'sdefinition,itreturnsapointerwhichpointstotypeT'szero-value.

    newreturnspointers.

    Thebuilt-infunctionmake(T,args)hasdifferentpurposesthannew(T).makecanbeusedforslice,map,andchannel,andreturnsatypeTwithaninitialvalue.Thereasonfordoingthisisbecausetheunderlyingdataofthesethreetypesmustbeinitializedbeforetheypointtothem.Forexample,aslicecontainsapointerthatpointstotheunderlyingarray,lengthandcapacity.Beforethesedataareinitialized,sliceisnil,soforslice,mapandchannel,makeinitializestheirunderlyingdataandassignssomesuitablevalues.

    makereturnsnon-zerovalues.

    Thefollowingpictureshowshownewandmakearedifferent.

    Figure2.5Underlyingmemoryallocationofmakeandnew

    Zero-valuedoesnotmeanemptyvalue.It'sthevaluethatvariablesdefaulttoinmostcases.Hereisalistofsomezero-values.

    int0int80int320int640uint0x0rune0//theactualtypeofruneisint32byte0x0//theactualtypeofbyteisuint8float320//lengthis4bytefloat640//lengthis8byteboolfalsestring""

    LinksDirectoryPrevioussection:"Hello,Go"Nextsection:Controlstatementsandfunctions

    Gofoundation

    42

  • 2.3ControlstatementsandfunctionsInthissection,wearegoingtotalkaboutcontrolstatementsandfunctionoperationsinGo.

    ControlstatementThegreatestinventioninprogrammingisflowcontrol.Becauseofthem,youareabletousesimplecontrolstatementsthatcanbeusedtorepresentcomplexlogic.Therearethreecategoriesofflowcontrol:conditional,cyclecontrolandunconditionaljump.

    if

    ifwillmostlikelybethemostcommonkeywordinyourprograms.Ifitmeetstheconditions,thenitdoessomethinganditdoessomethingelseifnot.

    ifdoesn'tneedparenthesesinGo.

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

    ThemostusefulthingconcerningifinGoisthatitcanhaveoneinitializationstatementbeforetheconditionalstatement.Thescopeofthevariablesdefinedinthisinitializationstatementareonlyavailableinsidetheblockofthedefiningif.

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

    //thefollowingcodewillnotcompilefmt.Println(x)

    Useif-elseformultipleconditions.

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

    gotoGohasagotokeyword,butbecarefulwhenyouuseit.gotoreroutesthecontrolflowtoapreviouslydefinedlabelwithinthebodyofsamecodeblock.

    Controlstatementsandfunctions

    43

  • funcmyFunc(){i:=0Here://labelendswith":"fmt.Println(i)i++gotoHere//jumptolabel"Here"}

    Thelabelnameiscasesensitive.

    for

    foristhemostpowerfulcontrollogicinGo.Itcanreaddatainloopsanditerativeoperations,justlikewhile.

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

    expression1,expression2andexpression3areallexpressions,whereexpression1andexpression3arevariabledefinitionsorreturnvaluesfromfunctions,andexpression2isaconditionalstatement.expression1willbeexecutedoncebeforelooping,andexpression3willbeexecutedaftereachloop.

    Examplesaremoreusefulthanwords.

    packagemain

    import"fmt"

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

    Sometimesweneedmultipleassignments,butGodoesn'thavethe,operator,soweuseparallelassignmentlikei,j=i+1,j-1.

    Wecanomitexpression1andexpression3iftheyarenotnecessary.

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

    Omit;aswell.Feelfamiliar?Yes,it'sidenticaltowhile.

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

    Therearetwoimportantoperationsinloopswhicharebreakandcontinue.breakjumpsoutoftheloop,andcontinueskipsthecurrentloopandstartsthenextone.Ifyouhavenestedloops,usebreakalongwithlabels.

    Controlstatementsandfunctions

    44

  • forindex:=10;index>0;index--{ifindex==5{break//orcontinue}fmt.Println(index)}//breakprints10、9、8、7、6//continueprints10、9、8、7、6、4、3、2、1

    forcanreaddatafromarray,slice,mapandstringwhenitisusedtogetherwithrange.

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

    BecauseGosupportsmulti-valuereturnsandgivescompileerrorswhenyoudon'tusevaluesthatweredefined,youmaywanttouse_todiscardcertainreturnvalues.

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

    Withgoyoucanaswellcreateaninfiniteloop,whichisequivalenttowhiletrue{...}inotherlanguges.

    for{//yourlogic}

    switchSometimesyoumayfindthatyouareusingtoomanyif-elsestatementstoimplementsomelogic,whichmaymakeitdifficulttoreadandmaintaininthefuture.Thisistheperfecttimetousetheswitchstatementtosolvethisproblem.

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

    ThetypeofsExpr,expr1,expr2,andexpr3mustbethesame.switchisveryflexible.Conditionsdon'thavetobeconstantsanditexecutesfromtoptobottomuntilitmatchesconditions.Ifthereisnostatementafterthekeywordswitch,thenitmatchestrue.

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

    Controlstatementsandfunctions

    45

  • Inthefifthline,weputmanyvaluesinonecase,andwedon'tneedtoaddthebreakkeywordattheendofcase'sbody.Itwilljumpoutoftheswitchbodyonceitmatchedanycase.Ifyouwanttocontinuetomatchingmorecases,youneedtousethefallthroughstatement.

    integer:=6switchinteger{case4:fmt.Println("integer

  • packagemain

    import"fmt"

    //returngreatervaluebetweenaandbfuncmax(a,bint)int{ifa>b{returna}returnb}

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

    max_xy:=max(x,y)//callfunctionmax(x,y)max_xz:=max(x,z)//callfunctionmax(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))//callfunctionhere}

    Intheaboveexample,therearetwoargumentsinthefunctionmax,theirtypesarebothintsothefirsttypecanbeomitted.Forinstance,a,bintinsteadofaint,bint.Thesamerulesapplyforadditionalarguments.Noticeherethatmaxonlyhasonereturnvalue,soweonlyneedtowritethetypeofitsreturnvalue-thisistheshortformofwritingit.

    Multi-valuereturn

    OnethingthatGoisbetteratthanCisthatitsupportsmulti-valuereturns.

    We'llusethefollowingexamplehere.

    packagemain

    import"fmt"

    //returnresultsofA+BandA*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)}

    Theaboveexamplereturnstwovalueswithoutnames-youhavetheoptionofnamingthemalso.Ifwenamedthereturnvalues,wewouldjustneedtousereturntoreturnthevaluessincetheyareinitializedinthefunctionautomatically.Noticethatifyourfunctionsaregoingtobeusedoutsideofthepackage,whichmeansyourfunctionnamesstartwithacapitalletter,you'dbetterwritecompletestatementsforreturn;itmakesyourcodemorereadable.

    funcSumAndProduct(A,Bint)(addint,multipliedint){add=A+Bmultiplied=A*Breturn}

    Controlstatementsandfunctions

    47

  • Variadicfunctions

    Gosupportsfunctionswithavariablenumberofarguments.Thesefunctionsarecalled"variadic",whichmeansthefunctionallowsanuncertainnumbersofarguments.

    funcmyfunc(arg...int){}

    arg…inttellsGothatthisisafunctionthathasvariablearguments.Noticethattheseargumentsaretypeint.Inthebodyoffunction,theargbecomesasliceofint.

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

    Passbyvalueandpointers

    Whenwepassanargumenttothefunctionthatwascalled,thatfunctionactuallygetsthecopyofourvariablessoanychangewillnotaffecttotheoriginalvariable.

    Let'sseeoneexampleinordertoprovewhati'msaying.

    packagemain

    import"fmt"

    //simplefunctiontoadd1toafuncadd1(aint)int{a=a+1//wechangevalueofareturna//returnnewvalueofa}

    funcmain(){x:=3

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

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

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

    Canyouseethat?Eventhoughwecalledadd1withx,theoriginvalueofxdoesn'tchange.

    Thereasonisverysimple:whenwecalledadd1,wegaveacopyofxtoit,notthexitself.

    NowyoumayaskhowIcanpasstherealxtothefunction.

    Weneedusepointershere.Weknowvariablesarestoredinmemoryandtheyhavesomememoryaddresses.So,ifwewanttochangethevalueofavariable,wemustchangeitsmemoryaddress.Thereforethefunctionadd1hastoknowthememoryaddressofxinordertochangeitsvalue.Herewepass&xtothefunction,andchangetheargument'stypetothepointertype*int.Beawarethatwepassacopyofthepointer,notcopyofvalue.

    Controlstatementsandfunctions

    48

  • packagemain

    import"fmt"

    //simplefunctiontoadd1toafuncadd1(a*int)int{*a=*a+1//wechangedvalueofareturn*a//returnnewvalueofa}

    funcmain(){x:=3

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

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

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

    Nowwecanchangethevalueofxinthefunctions.Whydoweusepointers?Whataretheadvantages?

    Allowsustousemorefunctionstooperateononevariable.Lowcostbypassingmemoryaddresses(8bytes),copyisnotanefficientway,bothintermsoftimeandspace,topassvariables.channel,sliceandmaparereferencetypes,sotheyusepointerswhenpassingtofunctionsbydefault.(Attention:Ifyouneedtochangethelengthofslice,youhavetopasspointersexplicitly)

    deferGohasawelldesignedkeywordcalleddefer.Youcanhavemanydeferstatementsinonefunction;theywillexecuteinreverseorderwhentheprogramexecutestotheendoffunctions.Inthecasewheretheprogramopenssomeresourcefiles,thesefileswouldhavetobeclosedbeforethefunctioncanreturnwitherrors.Let'sseesomeexamples.

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

    iffailureY{file.Close()returnfalse}

    file.Close()returntrue}

    Wesawsomecodebeingrepeatedseveraltimes.defersolvesthisproblemverywell.Itdoesn'tonlyhelpyoutowritecleancodebutalsomakesyourcodemorereadable.

    Controlstatementsandfunctions

    49

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

    Iftherearemorethanonedefers,theywillexecutebyreverseorder.Thefollowingexamplewillprint43210.

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

    Functionsasvaluesandtypes

    FunctionsarealsovariablesinGo,wecanusetypetodefinethem.Functionsthathavethesamesignaturecanbeseenasthesametype.

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

    What'stheadvantageofthisfeature?Theansweristhatitallowsustopassfunctionsasvalues.

    packagemain

    import"fmt"

    typetestIntfunc(int)bool//defineafunctiontypeofvariable

    funcisOdd(integerint)bool{returninteger%2!=0}

    funcisEven(integerint)bool{returninteger%2==0}

    //passthefunction`f`asanargumenttoanotherfunctionfuncfilter(slice[]int,ftestInt)[]int{varresult[]intfor_,value:=rangeslice{iff(value){result=append(result,value)}}returnresult}

    varslice=[]int{1,2,3,4,5,7}

    funcmain(){odd:=filter(slice,isOdd)even:=filter(slice,isEven)

    fmt.Println("slice=",slice)fmt.Println("Oddelementsofsliceare:",odd)fmt.Println("Evenelementsofsliceare:",even)}

    Controlstatementsandfunctions

    50

  • It'sveryusefulwhenweuseinterfaces.AsyoucanseetestIntisavariablethathasafunctionastypeandthereturnedvaluesandargumentsoffilterarethesameasthoseoftestInt.Therefore,wecanhavecomplexlogicinourprograms,whilemaintainingflexibilityinourcode.

    PanicandRecover

    Godoesn'thavetry-catchstructurelikeJavadoes.Insteadofthrowingexceptions,Gousespanicandrecovertodealwitherrors.However,youshouldn'tusepanicverymuch,althoughit'spowerful.

    Panicisabuilt-infunctiontobreakthenormalflowofprogramsandgetintopanicstatus.WhenafunctionFcallspanic,Fwillnotcontinueexecutingbutitsdeferfunctionswillcontinuetoexecute.ThenFgoesbacktothebreakpointwhichcausedthepanicstatus.Theprogramwillnotterminateuntilallofthesefunctionsreturnwithpanictothefirstlevelofthatgoroutine.paniccanbeproducedbycallingpanicintheprogram,andsomeerrorsalsocausepaniclikearrayaccessoutofboundserrors.

    Recoverisabuilt-infunctiontorecovergoroutinesfrompanicstatus.Callingrecoverindeferfunctionsisusefulbecausenormalfunctionswillnotbeexecutedwhentheprogramisinthepanicstatus.Itcatchespanicvaluesiftheprogramisinthepanicstatus,anditgetsniliftheprogramisnotinpanicstatus.

    Thefollowingexampleshowshowtousepanic.

    varuser=os.Getenv("USER")

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

    Thefollowingexampleshowshowtocheckpanic.

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

    mainfunctionandinitfunction

    Gohastworetentionswhicharecalledmainandinit,whereinitcanbeusedinallpackagesandmaincanonlybeusedinthemainpackage.Thesetwofunctionsarenotabletohaveargumentsorreturnvalues.Eventhoughwecanwritemanyinitfunctionsinonepackage,Istronglyrecommendwritingonlyoneinitfunctionforeachpackage.

    Goprogramswillcallinit()andmain()automatically,soyoudon'tneedtocallthembyyourself.Foreverypackage,theinitfunctionisoptional,butpackagemainhasoneandonlyonemainfunction.

    Programsinitializeandbeginexecutionfromthemainpackage.Ifthemainpackageimportsotherpackages,theywillbeimportedinthecompiletime.Ifonepackageisimportedmanytimes,itwillbeonlycompiledonce.Afterimportingpackages,programswillinitializetheconstantsandvariableswithintheimportedpackages,thenexecutetheinitfunctionifitexists,andsoon.Afteralltheotherpackagesareinitialized,programswillinitializeconstantsandvariablesinthemainpackage,thenexecutetheinitfunctioninsidethepackageifitexists.Thefollowingfigureshowstheprocess.

    Figure2.6FlowofprogramsinitializationinGo

    Controlstatementsandfunctions

    51

  • import

    WeuseimportveryofteninGoprogramsasfollows.

    import("fmt")

    Thenweusefunctionsinthatpackageasfollows.

    fmt.Println("helloworld")

    fmtisfromGostandardlibrary,itislocatedwithin$GOROOT/pkg.Gosupportsthird-partypackagesintwoways.

    1. Relativepathimport"./model"//loadpackageinthesamedirectory,Idon'trecommendthisway.2. Absolutepathimport"shorturl/model"//loadpackageinpath"$GOPATH/pkg/shorturl/model"

    Therearesomespecialoperatorswhenweimportpackages,andbeginnersarealwaysconfusedbytheseoperators.

    1. Dotoperator.Sometimeweseepeopleusefollowingwaytoimportpackages.

    import(."fmt")

    Thedotoperatormeansyoucanomitthepackagenamewhenyoucallfunctionsinsideofthatpackage.Nowfmt.Printf("Helloworld")becomestoPrintf("Helloworld").

    2. Aliasoperation.Itchangesthenameofthepackagethatweimportedwhenwecallfunctionsthatbelongtothatpackage.

    import(f"fmt")

    Nowfmt.Printf("Helloworld")becomestof.Printf("Helloworld").3. _operator.Thisistheoperatorthatisdifficulttounderstandwithoutsomeoneexplainingittoyou.

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

    The_operatoractuallymeanswejustwanttoimportthatpackageandexecuteitsinitfunction,andwearenotsureifwewanttousethefunctionsbelongingtothatpackage.

    LinksDirectoryPrevioussection:GofoundationNextsection:struct

    Controlstatementsandfunctions

    52

  • 2.4struct

    structWecandefinenewtypesofcontainersofotherpropertiesorfieldsinGojustlikeinotherprogramminglanguages.Forexample,wecancreateatypecalledpersontorepresentaperson,withfieldsnameandage.Wecallthiskindoftypeastruct.

    typepersonstruct{namestringageint}

    Lookhoweasyitistodefineastruct!

    Therearetwofields.

    nameisastringusedtostoreaperson'sname.ageisaintusedtostoreaperson'sage.

    Let'sseehowtouseit.

    typepersonstruct{namestringageint}

    varPperson//pispersontype

    P.name="Astaxie"//assign"Astaxie"tothefield'name'ofpP.age=25//assign25tofield'age'ofpfmt.Printf("Theperson'snameis%s\n",P.name)//accessfield'name'ofp

    Therearethreemorewaystoinitializeastruct.

    Assigninitialvaluesbyorder

    P:=person{"Tom",25}

    Usetheformatfield:valuetoinitializethestructwithoutorder

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

    Defineananonymousstruct,theninitializeit

    P:=struct{namestring;ageint}{"Amy",18}

    Let'sseeacompleteexample.

    struct

    53

  • packagemain

    import"fmt"

    //defineanewtypetypepersonstruct{namestringageint}

    //structispassedbyvalue//comparetheageoftwopeople,thenreturntheolderpersonanddifferencesofagefuncOlder(p1,p2person)(person,int){ifp1.age>p2.age{returnp1,p1.age-p2.age}returnp2,p2.age-p1.age}

    funcmain(){vartomperson

    tom.name,tom.age="Tom",18bob:=person{age:25,name:"Bob"}paul:=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)}

    embeddedfieldsinstructI'vejustintroducedtoyouhowtodefineastructwithfieldnamesandtype.Infact,Gosupportsfieldswithoutnames,butwithtypes.Wecalltheseembeddedfields.

    Whentheembeddedfieldisastruct,allthefieldsinthatstructwillimplicitlybethefieldsinthestructinwhichithasbeenembedded.

    Let'sseeoneexample.

    struct

    54

  • packagemain

    import"fmt"

    typeHumanstruct{namestringageintweightint}

    typeStudentstruct{Human//embeddedfield,itmeansStudentstructincludesallfieldsthatHumanhas.specialtystring}

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

    //accessfieldsfmt.Println("Hisnameis",mark.name)fmt.Println("Hisageis",mark.age)fmt.Println("Hisweightis",mark.weight)fmt.Println("Hisspecialtyis",mark.specialty)

    //modifymark'sspecialtymark.specialty="AI"fmt.Println("Markchangedhisspecialty")fmt.Println("Hisspecialtyis",mark.specialty)

    fmt.Println("Markbecomeold.Heisnotanathleteanymore")mark.age=46mark.weight+=60fmt.Println("Hisageis",mark.age)fmt.Println("Hisweightis",mark.weight)}

    Figure2.7EmbeddinginStudentandHuman

    WeseethatwecanaccesstheageandnamefieldsinStudentjustlikewecaninHuman.Thisishowembeddedfieldswork.It'sverycool,isn'tit?Holdon,there'ssomethingcooler!YoucanevenuseStudenttoaccessHumaninthisembeddedfield!

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

    AllthetypesinGocanbeusedasembeddedfields.

    struct

    55

  • packagemain

    import"fmt"

    typeSkills[]string

    typeHumanstruct{namestringageintweightint}

    typeStudentstruct{Human//structasembeddedfieldSkills//stringsliceasembeddedfieldint//built-intypeasembeddedfieldspecialtystring}

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

    Intheaboveexample,wecanseethatalltypescanbeembeddedfieldsandwecanusefunctionstooperateonthem.

    Thereisonemoreproblemhowever.IfHumanhasafieldcalledphoneandStudenthasafieldwithsamename,whatshouldwedo?

    Gouseaverysimplewaytosolveit.Theouterfieldsgetupperaccesslevels,whichmeanswhenyouaccessstudent.phone,wewillgetthefieldcalledphoneinstudent,nottheoneintheHumanstruct.Thisfeaturecanbesimplyseenasfieldoverloading.

    struct

    56

  • packagemain

    import"fmt"

    typeHumanstruct{namestringageintphonestring//Humanhasphonefield}

    typeEmployeestruct{Humanspecialtystringphonestring//phoneinemployee}

    funcmain(){Bob:=Employee{Human{"Bob",34,"777-444-XXXX"},"Designer","333-222"}

    fmt.Println("Bob'sworkphoneis:",Bob.phone)fmt.Println("Bob'spersonalphoneis:",Bob.Human.phone)}

    LinksDirectoryPrevioussection:ControlstatementsandfunctionsNextsection:Object-oriented

    struct

    57

  • Object-orientedWetalkedaboutfunctionsandstructsinthelasttwosections,butdidyoueverconsiderusingfunctionsasfieldsofastruct?Inthissection,Iwillintroduceyoutoanotherformoffunctionthathasareceiver,whichiscalledamethod.

    methodSupposeyoudefinea"rectangle"structandyouwanttocalculateitsarea.We'dtypicallyusethefollowingcodetoachievethisgoal.

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

    Theaboveexamplecancalculatearectangle'sarea.Weusethefunctioncalledarea,butit'snotamethodoftherectanglestruct(likeclassmethodsinclassicobject-orientedlanguages).Thefunctionandstructaretwoindependentthingsasyoumaynotice.

    It'snotaproblemsofar.However,ifyoualsohavetocalculatetheareaofacircle,square,pentagon,oranyotherkindofshape,youaregoingtoneedtoaddadditionalfunctionswithverysimilarnames.

    Figure2.8Relationshipbetweenfunctionandstruct

    Obviouslythat'snotcool.Also,theareashouldreallybethepropertyofacircleorrectangle.

    Thisiswhereamethodcomestoplay.Themethodisafunctionaffiliatedwithatype.Ithassimilarsyntaxasfunctionexcept,afterthefunckeywordhasaparametercalledthereceiver,whichisthemainbodyofthatmethod.

    Usingthesameexample,Rectangle.Area()belongsdirectlytorectangle,insteadofasaperipheralfunction.Morespecifically,length,widthandArea()allbelongtorectangle.

    AsRobPikesaid.

    "Amethodisafunctionwithanimplicitfirstargument,calledareceiver."

    Syntaxofmethod.

    func(rReceiverType)funcName(parameters)(results)

    Let'schangeourexampleusingmethodinstead.

    Object-oriented

    58

  • packagemain

    import("fmt""math")

    typeCirclestruct{radiusfloat64}

    typeRectanglestruct{width,heightfloat64}

    //methodfunc(cCircle)Area()float64{returnc.radius*c.radius*math.Pi}

    //methodfunc(rRectangle)Area()float64{returnr.width*r.height}

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

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

    Notesforusingmethods.

    Ifthenameofmethodsarethesamebuttheydon'tsharethesamereceivers,theyarenotthesame.Methodsareabletoaccessfieldswithinreceivers.Use.tocallamethodinthestruct,thesamewayfieldsarecalled.

    Figure2.9Methodsaredifferentindifferentstructs

    Intheexampleabove,theArea()methodsbelongtobothRectangleandCirclerespectively,sothereceiversareRectangleandCircle.

    Onethingthat'sworthnotingisthatthemethodwithadottedlinemeansthereceiverispassedbyvalue,notbyreference.Thedifferencebetweenthemisthatamethodcanchangeitsreceiver'svalueswhenthereceiverispassedbyreference,anditgetsacopyofthereceiverwhenthereceiverispassedbyvalue.

    Canthereceiveronlybeastruct?Ofcoursenot.Anytypecanbethereceiverofamethod.Youmaybeconfusedaboutcustomizedtypes.Structisaspecialkindofcustomizedtype-therearemorecustomizedtypes.

    Usethefollowingformattodefineacustomizedtype.

    typetypeNametypeLiteral

    Examplesofcustomizedtypes:

    Object-oriented

    59

  • typeageinttypemoneyfloat32typemonthsmap[string]int

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

    Ihopethatyouknowhowtousecustomizedtypesnow.SimilartotypedefinC,weuseagestosubstituteintintheaboveexample.

    Let'sgetbacktotalkingaboutmethod.

    Youcanuseasmanymethodsincustomtypesasyouwant.

    packagemain

    import"fmt"

    const(WHITE=iotaBLACKBLUEREDYELLOW)

    typeBoxstruct{width,height,depthfloat64colorColor}typeColorbytetypeBoxList[]Box//asliceofboxes

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

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

    //methodfunc(blBoxList)BiggestsColor()Color{v:=0.00k:=Color(WHITE)for_,b:=rangebl{ifb.Volume()>v{v=b.Volume()k=b.color}}returnk}

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

    //methodfunc(cColor)String()string{

    Object-oriented

    60

  • 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.BiggestsColor().String())

    //Let'spaintthemallblackboxes.PaintItBlack()

    fmt.Println("Thecolorofthesecondoneis",boxes[1].color.String())fmt.Println("Obviously,now,thebiggestoneis",boxes.BiggestsColor().String())}

    Wedefinesomeconstantsandcustomizedtypes.

    UseColorasaliasofbyte.DefineastructBoxwhichhasfieldsheight,width,lengthandcolor.DefineastructBoxListwhichhasBoxasitsfield.

    Thenwedefinedsomemethodsforourcustomizedtypes.

    Volume()usesBoxasitsreceiverandreturnsthevolumeofBox.SetColor(cColor)changesBox'scolor.BiggestsColor()returnsthecolorwhichhasthebiggestvolume.PaintItBlack()setscolorforallBoxinBoxListtoblack.String()useColorasitsreceiver,returnsthestringformatofcolorname.

    Isitmuchclearerwhenweusewordstodescribeourrequirements?Weoftenwriteourrequirementsbeforewestartcoding.

    Usepointerasreceiver

    Let'stakealookatSetColormethod.ItsreceiverisapointerofBox.Yes,youcanuse*Boxasareceiver.Whydoweuseapointerhere?BecausewewanttochangeBox'scolorinthismethod.Thus,ifwedon'tuseapointer,itwillonlychangethevalueinsideacopyofBox.

    Ifweseethatareceiveristhefirstargumentofamethod,it'snothardtounderstandhowitworks.

    Youmightbeaskingwhywearen'tusing(*b).Color=cinsteadofb.Color=cintheSetColor()method.EitheroneisOKherebecauseGoknowshowtointerprettheassignment.DoyouthinkGoismorefascinatingnow?

    Youmayalsobeaskingwhetherweshoulduse(&bl[i]).SetColor(BLACK)inPaintItBlackbecausewepassapointertoSetColor.Again,eitheroneisOKbecauseGoknowshowtointerpretit!

    Inheritanceofmethod

    Welearnedaboutinheritanceoffieldsinthelastsection.Similarly,wealsohavemethodinheritanceinGo.Ifananonymousfieldhasmethods,thenthestructthatcontainsthefieldwillhaveallthemethodsfromitaswell.

    Object-oriented

    61

  • packagemain

    import"fmt"

    typeHumanstruct{namestringageintphonestring}

    typeStudentstruct{Human//anonymousfieldschoolstring}

    typeEmployeestruct{Humancompanystring}

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

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

    sam.SayHi()mark.SayHi()}

    MethodOverridingIfwewantEmployeetohaveitsownmethodSayHi,wecandefineamethodthathasthesamenameinEmployee,anditwillhideSayHiinHumanwhenwecallit.

    Object-oriented

    62

  • packagemain

    import"fmt"

    typeHumanstruct{namestringageintphonestring}

    typeStudentstruct{Humanschoolstring}

    typeEmployeestruct{Humancompanystring}

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

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

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

    sam.SayHi()mark.SayHi()}

    YouareabletowriteanObject-orientedprogramnow,andmethodsuseruleofcapitallettertodecidewhetherpublicorprivateaswell.

    LinksDirectoryPrevioussection:structNextsection:interface

    Object-oriented

    63

  • 2.6Interface

    InterfaceOneofthesubtlestdesignfeaturesinGoareinterfaces.Afterreadingthissection,youwilllikelybeimpressedbytheirimplementation.

    Whatisaninterface

    Inshort,aninterfaceisasetofmethodsthatweusetodefineasetofactions.

    Liketheexamplesinprevioussections,bothStudentandEmployeecanSayHi(),buttheydon'tdothesamething.

    Let'sdosomemorework.We'lladdonemoremethodSing()tothem,alongwiththeBorrowMoney()methodtoStudentandtheSpendSalary()methodtoEmployee.

    Now,StudenthasthreemethodscalledSayHi(),Sing()andBorrowMoney(),andEmployeehasSayHi(),Sing()andSpendSalary().

    ThiscombinationofmethodsiscalledaninterfaceandisimplementedbybothStudentandEmployee.So,StudentandEmployeeimplementtheinterface:SayHi()andSing().Atthesametime,Employeedoesn'timplementtheinterface:BorrowMoney(),andStudentdoesn'timplementtheinterface:SpendSalary().ThisisbecauseEmployeedoesn'thavethemethodBorrowMoney()andStudentdoesn'thavethemethodSpendSalary().

    TypeofInterfaceAninterfacedefinesasetofmethods,soifatypeimplementsallthemethodswesaythatitimplementstheinterface.

    interface

    64

  • typeHumanstruct{namestringageintphonestring}

    typeStudentstruct{Humanschoolstringloanfloat32}

    typeEmployeestruct{Humancompanystringmoneyfloat32}

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

    typeYoungChapinterface{SayHi()Sing(songstring)BorrowMoney(amountfloat32)}

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

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

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

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

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

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

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

    Weknowthataninterfacecanbeimplementedbyanytype,andonetypecanimplementma