Create Your First Golang App - Hackers and Slackers
文章推薦指數: 80 %
Set up a local Golang environment and learn the basics to create and publish your first 'Hello world' app. AboutSeriesJoinSearchDonateSearchPostsNoresultsfor'undefined'OpenMenuSearchPostsNoresultsfor''TrendingSearchespythonjavascriptflasktestpythonflaskapplsqlachemytableaudjangogolangplotlybigquerystringCloseMenuOpenMenuHomeAboutSearchTagsPythonSoftwareDevOpsDataEngineeringArchitecturePandasDataAnalysisDataScienceRESTAPIsSQLCodeSnippetCornerFlaskJavaScriptAWSNodeJSSeriesBuildFlaskAppsDataAnalysiswithPandasGoogleCloudArchitectureLearningApacheSparkCreateaRESTAPIinAWSWorkingwithMySQLGraphQLTutorialsHackingTableauServerMasteringSQLAlchemyMongoDBAtlasCloudArchitectureWelcometoSQLMappingDatawithMapboxMicrosoftPowerPivotGettingStartedwithDjangoWebScrapingWithPythonAuthorsToddBirchardMaxMileafGrahamBeckleyDavidAquinoMatthewAlhonteRyanRosadoPaulArmstrongDylanCastilloJoinRSSDonateCloseMenuCreateYourFirstGolangAppToddGolang12minreadMay25Tobehumanistobeanunwillingpassengerinawinding,aimlessjourneywecalllife.Eachofushasfelttheeternalsolidarityoftimebreakapartaswearethrustintoexistencetonavigatethetribulationsofexisting,leftonlytowonderwhatthepointofitallis.Justaswebecomecomplacentinourrespectiveexistentialstruggles,aneventofunspeakableforceshakesthefoundationsofourreality:wefallinlove.Fallinginloveisasexhaustingasitisenchanting.Ourlifespansonlyhavethewillingcapacitytofallinloveafinitenumberoftimes,ifatall.Thisrealizationisresponsibleformakinguswaryoffallinginloveinthefirstplace,aswellaszealouslydefendingthelovewe'vefoundagainstpotentialintruders.I'monetoadvocateforanoppositeconclusion.Asdifficult,scary,ortime-consumingaslovemaybe,Iarguethatalifethathasdiscoveredloveonmultipleoccasionsisalifewell-lived.Ifthatmakesmeaslut,sobeit:Iamaslutforprogramminglanguages.I'veproudlymaintainedalong-termlovingcommitmenttoPython,aswellasacomplicatedaffairwithJavaScript.Still,eventhispromiscuouslifestylecanleaveoneyearningforakindoflovethatonlyastatically-typedlanguagecandeliver.Asourrelationshipstransitionfromscriptinghoneymoonstomatureenterprise-levelendeavors,it'snaturaltosecond-guessourchoices.WhyenduretheoverheadofadynamicallytypedlanguagewhenweendupannotatingtypeswithMyPy?Couldtherebevalidityinargumentsthatclaimourlanguageofchoiceis"slow?"AnddowereallythinkwecanputupwithbaggageknownastheGILtilldeathdouspart?IfthisallseemslikearoundaboutwaytoannouncethatI'vebeenfoolingaroundwithGolang,that'sbecauseitabsolutelyis.Idon'tsuspectthatmanypeoplearewillingorcapableofleavingtheircomfortzonestopartakeinajourneyofthismagnitude.Fortherestofyou,I'dliketowelcomeyoubymysideforashortmomentinourlivestoexploretheunexplored.Whoknows,perhapsyou'llevenfindlovealongtheway.InstallationandSetupInstallingonOSXissimplethankstoHomebrew:$brewupdate $brewinstallgolangInstallGolangviaHomebrewGOPATHvsGOROOTInstallingGolangviaHomebrewautomaticallygeneratestwodirectoriescriticaltorunningGo:GOROOT(/usr/local/go):TheGo"root"directorycontainsGo'ssourcecode.Homebrewwillautomaticallyregisterthispathforyou;there'slittlereasontomessaroundinhereunlessyou'reaGocontributororifyou'reattemptingtorunmultipleversionsofGo.GOPATH(/Users/toddbirchard/go):Unlikemostprogramminglanguages,GotakesanopinionatedstancethatallprojectsanddependenciesofthelanguageshouldexistinasingledirectoryknownastheGOPATH.AnytimewedevelopaGoprojectorinstallathird-partymodule,theactionstakenultimatelyhappeninsidethisdirectory.TomakesureOSXrecognizesour GOPATH,we'llhavetoaddittoourshell'sstartupscript.Openyour.bashrc,.zshrc,orwhateveritisyouuse:$vim~/.zshrcModifyshellscriptWe'regoingtoaddthe/gobasedirectory,aswellasthesubdirectory/go/bin:exportGOPATH=/Users/toddbirchard/go exportPATH=$PATH:$GOPATH exportPATH=$PATH:$GOPATH/binAddGOPATHtoyourPATHSavethisandreloadyourshellscript:.~/.zshrcActivechangesLet'smakesureeverythingwentasplanned:$goversion >>goversiongo1.14.2darwin/amd64VerifyInstallationAndasalastbitofduediligence,let'sconfirmthatourGOPATHisbeingrecognizedcorrectly:$goenvGOPATH >>/Users/toddbirchard/goVerifyGOPATHAsanaside,goisGolang'sCLIwhichisessentialforcompiling,formatting,andrunningGocode,aswellasinstallingmodules(we'llgettothoseinasec).Tryrunninggohelptogetacquainted.AnatomyofGOPATHGolang'sGOPATHisadirectorywhereallyourGocodeandprojectdependencieslive.ThegoCLIactuallyhasabuilt-incommand$gohelpgopathwhichexplainsthisquitewell:TheGopathisusedtoresolveimportstatements.Itisimplementedbyanddocumentedinthego/buildpackage.TheGOPATHenvironmentvariablelistsplacestolookforGocode.SimilartohowPythonlooksforimportedlibrariesinthePythonpath,GosearchestheGOPATHforthesame.AnotabledifferencebetweenPythonandGopathsisthatGoexpectsallyourGoprojectstolivewithintheGOPATH,specifically/go/src.ContrastthiswithPythonwhereprojectscanliveanywhere.TheGOPATHdirectoryismadeupof3subdirectories:/go ├──/bin ├──/pkg └──/srcStructureofourGOPATH.$gohelpgopathexplainsthepurposeofeachofthesedirectories.src:Thesrcdirectoryholdssourcecode.Thepathbelowsrcdeterminestheimportpathorexecutablename.pkg:Thepkgdirectoryholdsinstalledpackageobjects.AsintheGotree,eachtargetoperatingsystemandarchitecturepairhasitsownsubdirectoryofpkg(pkg/GOOS_GOARCH).bin:Thebindirectoryholdscompiledcommands.Eachcommandisnamedforitssourcedirectory,butonlythefinalelement,nottheentirepath.Inshort,yourpersonalsourcecodebelongsin/src,installedthird-partypackageswilllivein/pkg,andthird-partycommandswhichextendthegoCLIwilllivein/bin.Togiveanexample,here'swhatmypathlookslike:/go ├──/bin │├──golint │└──tour ├──/pkg │├──/darwin_amd64 ││├──github.com ││├──go-pandas.a ││├──golangwebsite ││└──hustlers │├──/mod ││├──/cache ││├──/cloud.google.com │││└──[email protected] ││├──/github.com │││├──/google ││││└──[email protected] │││├──/gorilla ││││└──[email protected] │││├──/mattn ││││└──[email protected] │││├──/olekukonko ││││└──[email protected] │││└──/rocketlaunchr │││└──[email protected] ││└──golang.org │└──/sumdb │└──sum.golang.org └──/src ├──/golang-helloworld │├──README.md │├──go.mod │├──go.sum │├──golang-helloworld │└──main.go ├──/golang.org │└──x └──/hustlers ├──README.md ├──go.mod ├──go.sum ├──hustlers ├──main.go ├──main_test.go ├──static ├──templates └──vendorMyGOPATH.Weshouldbeabletobreakthisdownquiteeasily./bincontainstwoGocommandsIinstalledpreviously.golintisathird-partylinterforGo,and"tour"isalocalversionoftheofficialTourofGowalkthroughtohelpGonewcomerslearntheirwayaroundthelanguage(Ihighlyrecommendcompletingthis,btw)./pkgcontainsthepackagesI'veinstalled.Payspecialattentionto/pkg/mod,whereyoucanseeI'veinstalledseveralpackagesfromGithubunderthe/github.comdirectory.Thesepackagesincludedataframe-go,whichisaGoimplementationofPandas-likeDataFrames,aswellasmux,whichisanHTTProuterthatwe're goingtouseinourfirsthello-worldproject./srchasthreeprojectsI'veworkedonalready.golang-helloworldistheprojectwe'reabouttocreateinthistutorial.GolangTerminologyBeforewegettocoding,let'sbrushuponsomebasicGovocabulary:Packages:Goprogramsaremadeupof"packages,"whichmirrorpackagingconceptsinotherprogramminglanguages(thinkmodulesinPythonorpackagesinJava).EveryGolangprogramcontainsapackagecalledmain,whichservesastheproject'sentrypoint.Modules:Gomodulesarethird-partylibrariesinstalledbyGo.Modulesareessentiallyprojectswhichhavebeenpublishedforgeneraluseasdependenciesinyourprojects.Vendors:Thisiswherethingsgetinteresting.Whilemodulescanbeinstalledtothe/pkg/moddirectoryforglobaluse,sourceprojectscancontaintheirownversionsofthesemodulestoavoidclashingdependencyversionsbetweenprojects(thisisnotdissimilartoPythonvirtualenvironments).Whilenotrequired,youcanchoosetokeepmoduleversionsproject-specific(wewilldothisinourexample).CreatingaHelloWorldAppEnoughchit-chat,let'smakeourfirstGoproject.Westartwithcreatingourproject'sdirectoryinthe/go/srcdirectory:$cd$GOPATH/src $mkdirgolang-helloworld $cdgolang-helloworld Whileinsideournewprojectdirectory,we'renowgoingtoinitializeourprojectasaGomodule.ThismeansanybodywillbeabletoinstallourGocodeoffGithubiftheysochoose.IknowI'mgoingtosavemyrepotogithub.com/hackersandslackers/golang-helloworld,sowerunthefollowing:$gomodinitgithub.com/hackersandslackers/golang-helloworld >>go:creatingnewgo.mod:modulegithub.com/hackersandslackers/golang-helloworldCreatingaGomodule.Themomentthisisdone,anewfilewillappearinyourdirectorycalledgo.mod.Checkoutthecontentsusing$catgo.modtoseewhatthisinitializeswith:modulegithub.com/hackersandslackers/golang-helloworld go1.14go.modPrettysimplestuffsofar!go.modcontainsinformationaboutourmoduleforothers,suchasthemodulenameandGoversionitisintendedfor.Asweinstalldependenciesforourproject,thesedependenciesandtheirrespectiveversionswillbestoredhere.main.goAsmentioned,everyGoproject'sentrypointisafilecalledmain.go.We'regoingtocreatethemostsimplemain.gofileimaginable:ascriptwhichoutputs"Hello,world.":packagemain import"fmt" funcmain(){ fmt.Println("Hello,world.") }main.goNowremember:sinceGoisacompiledlanguage,weneedtobuildourprojectbeforewecanrunit 😮.Iknowtheextraeffortisnearlyunbearable,butthingsareabouttopayoffasyouwitnessthefruitsofyourlabor:$gobuild $gorunmain.go >>Hello,world. Buildandrunyourmodule.WEDIDIT!We'vejustcreatedourfirst"helloworld"appinGo.Yourprojectstructureshouldnowlooksomethinglikethis:/golang-helloworld ├──go.mod ├──golang-helloworld └──main.go Ourprojectsofar.Thenewlycreatedgolang-helloworldfileisthecompiledexecutablewhichiscreatedeachtimewerun$gobuild.Eachtimewemakechangestooursourcecode,weshouldrun$gobuildagaintorebuildthisexecutablewithourchanges.Bonus:CodeFormattingAniftytoolthatcomesout-of-the-boxinGoisacodeformattertocleanupanyuglyindentsandsuchinyoursource.Trymessinguptheindentsinmain.goandrunthefollowing:$gofmt >>main.goFormattingsourcecode.Thisshouldfixalltheuglyformattinginthefilenamesinoutputs,inourcasemain.go.CreateaWebAppIfweweretoleaveoffwithastupidprogramthatprints"Hello,world!",I'dbedoingyouadisservice.Whilewe'vesetupGolangsuccessfully,wehaven'tlearnedmuchaboutcreatinganythingusefulyet.It'stimeforustokickthingsupanotchbymakingourappawebappwhichcanbeservedfromabrowser.InstallingourFirstDependencyToserveGocodeviaawebserver,we'regoingtoleveragethehighlypopulargorilla/muxmodule:alightweightrequestrouteranddispatcherformatchingincomingrequeststotheirrespectivehandler:gorilla/muxApowerfulHTTProuterandURLmatcherforbuildingGowebserverswith🦍-gorilla/muxGitHubgorillaWe'regoingtoinstallthisbyrunning$gogetfollowedby$goinstall:$goget-ugithub.com/gorilla/mux $goinstallgithub.com/gorilla/muxInstalladependency.gogetinstallsthesourceforgorilla/muxtoour/go/bindirectory.The-uflagwepassisan"update"flag,whichweusetograbthelatestversionjustincase.Let'sseehowgo.modwasaffectedbyrunning$catgo.mod:modulegithub.com/hackersandslackers/golang-helloworld go1.14 requiregithub.com/gorilla/muxv1.7.4go.modAspromised,ourmoduledependencyhasnowbeenaddedtogo.modalongwiththeproperversionnumber.Nowwecanimportanduse"github.com/gorilla/mux"tohelpusbuildaproject!Wecanalsouse$gomodvendortobuildthisdependencyinour/vendorsfoldertokeepitlocaltoourproject.Here'sawallofcodewhichturnsourhelloworldappintoawebapp:packagemain import( "github.com/gorilla/mux" "log" "net/http" "time" "io" ) funchandler(whttp.ResponseWriter,r*http.Request){ io.WriteString(w,"Hello,world!\n") } //Routedeclaration funcrouter()*mux.Router{ r:=mux.NewRouter() r.HandleFunc("/",handler) returnr } //Initiatewebserver funcmain(){ router:=router() srv:=&http.Server{ Handler:router, Addr:"127.0.0.1:9100", WriteTimeout:15*time.Second, ReadTimeout:15*time.Second, } log.Fatal(srv.ListenAndServe()) }main.goOurfunctionsaremain(),router(),andhandler(),whichgetexecutedinthatorder.main()main()setsupanHTTPservertobeservedlocallyonport9100,withacoupleread&writetimeoutssetasaformofbestpractice.Ourserverdoesn'tdomuchonitsownwithoutanyroutestoresolve.That'swhereourrouter()functioncomesin.router()Weinitializea"router"bycreatedvariablerwithr:=mux.NewRouter().Fromtherewecansetasmanyroutesaswe'dlikewiththefollowingsyntax:r.HandleFunc([URL_ROUTE],[FUNCTION_TO_EXECUTE])Settingaroutewithmux.HandleFunc()isabuilt-inmethodtoresolveURLroutes.ThefirstparameteristhetargetURL,andthesecondisthenameofafunctiontobeexecutedwhenauserrequestssaidroute.Weonlyspecifyasinglerouteinourexample,butwecouldtheoreticallysetasmanyaswe'dlike,forexample:r:=mux.NewRouter() r.HandleFunc("/",homeHandler) r.HandleFunc("/about",aboutHandler) r.HandleFunc("/contact",contactHandler) returnrExampleofsettingmultipleroutes.handler()Muxhandlerfunctionsalwaysaccepttwoparametersbydefault,whichessentiallyresolvetooutputandinput.whttp.ResponseWriterexpectsaparameternamedwwiththetypehttp.ResponseWriter,whichiswhatwereturntorendersomethingfortheend-user.r*http.Requestcontainsinformationabouttheuser'srequest,savedtoaparameternamedr.We'rekeepingthingssimple(ish)today,sowe'llsettleforourroutetosimpleoutputa"helloworld"messageforourroute:io.WriteString(w,"Hello,world!\n")Outputastring.Rebuildandrunourprojectwith$gobuildand$gorunmain.go.Nowtryvisiting127.0.0.1:9100inyourbrowser:OurliveGoapp.Andthereyouhaveit,lovebirds.BestPracticesBeforeIleavetogiveyouandyournewfavoriteGophersomeprivatetime,there'ssomeverylow-hangingfruitworthpickinginanintrotutorial.Thiswon'tlastlong."Exported"Functions(AKA:PublicVersusPrivate)Nearlyeveryprogramminglanguagehastheconceptof"private"versus"public"functions.Gohasthisconceptaswellregardingsharedfunctionsbetweenpackages.Functionsthatare"shared"arereferredtoas"exportedfunctions"(supJavaScript).Anameisexportedifitbeginswithacapitalletter.Ourhelloworldexampleconsistedsolelyofprivatefunctions(whichmakessense,asweonlyhadasinglepackage).Ifwewantedtomakeourrouter()functionaccessiblebyotherpackages,we'dsimplyneedtorenamethistoRouter().TypeDeclarationGoexpectsthatvariables,incomingfunctionparameters,andfunctionreturnvaluestohavedeclaredtypes.Inthebelowexample,thefunctionadd()acceptstwointegersandaddsthem,whichundoubtedlyresultsinaninteger:funcadd(xint,yint)int{ returnx+y }Settingtypesforincomingfunctionparameters.Variablesaresetusingthesamesyntaxasfunctionparameters,withthevariablenamecomingfirst:varxint=0SettingasingleintegervariableThere'salsoashorthandwayofsettingmultiplevariablesofthesametypebyseparatingvariablenamesbycommas.Inthiscase,variablesx,y,andzaresetasintegerswithnoassignedvalues:varx,y,zintCreating3variableseachsharingtheinttype.ShortAssignmentStatementsAverycoolfeatureofGoisthe:=operator.The"shortassignment"operatorcanbeusedtosetmultiplevariablesatoncewithimplicittypes.ThatmeansGowillresolvethetypeofeachvariableonitsownbasedonthevalueassignedwithouttheneedforexplicittypedeclaration.Thebelowexamplecreatesthreevariables,wherexandyareresolvedasbooleans,andzisresolvedasastring:funcmain(){ x,y,z:=true,false,"no!" }Implicitlysetvariabletypeswiththe:=operator.ConstantsThelastnoteworthynuggetisthepresenceofconstantsinGo.Whilethere'snothinguniqueaboutGosupportingconstants,it'sabreathoffreshairforPythonistaswhomaybenostalgicabouthavingtheabilitytodothefollowing:constWebsite="hackersandslackers.com"HappilyEverAfter?WhetherornotyouhopontheGotrainisaquestionofwhereyourheartlies.WhileI'llcontinueusingPythonforthemajorityofwhatIdo,it'snicetoleavetheMrs.athomeonceinawhile(inb4thismisogynisticanalogyruinsme)tofoolaroundbuildingquickendpointsinastatically-typedlanguagewhichisn'tJava.HaveIevermentionedhowmuchIhateOracle?Like,howmuchIreallyhatethem?No?Perhapsanothertime.Anyway,getonwithitthen.Therepositoryforwhatwe'vecreatedtodayisuponGithubhere:hackersandslackers/golang-helloworldCreateyourfirst“Helloworld”appwritteninGolang.-hackersandslackers/golang-helloworldGitHubhackersandslackersGolangSoftwareToddBirchard123PostsNewYorkCitySiteEngineerwithanongoingidentitycrisis.Breakseverythingbeforelearningbestpractices.Completelynormalandemotionallystable.Engineerwithanongoingidentitycrisis.Breakseverythingbeforelearningbestpractices.Completelynormalandemotionallystable.DeployaGolangWebApplicationBehindNginxGolang,DevOpsCommentSubmitted!Yourcommentwillbevisibleshortly.UserIDPostSlugPostIDUserEmailUserNameUserAvatarUserProviderAuthorNameAuthorEmailAddressCommentHavesomethingtosay?WritePreviewHavesomethingtosay?SignintocommentMonthlyNewsletterNameEmailPhoneSignUpSupportusWestartedsharingthesetutorialstohelpandinspirenewscientistsandengineersaroundtheworld.IfHackersandSlackershasbeenhelpfultoyou,feelfreetobuyusacoffeetokeepusgoing:).Buymeacoffee
延伸文章資訊
- 1A Go package for building Progressive Web Apps
A package for building progressive web apps (PWA) with the Go programming language (Golang) and W...
- 2Golang
Go is an open source programming language that makes it easy to build simple ... and support for ...
- 3Best Golang Applications: 6 Companies Using the Go Language
Top Golang Apps – 6 Best Apps Made With Golang · 1. Golang banking app – Monzo · 2. Golang ecomme...
- 4分享下使用Golang + React Native开发APP的体验 - 知乎专栏
Golang从1.5版本开始就可以编写android端、ios端的移动应用了,但貌似尝试的人很少最近由于我闲得蛋疼,所以用Golang的写了个看小说的APP,下面说下开发中遇到的事。
- 5Writing Web Applications - go.dev
Go is an open source programming language that makes it easy to build simple, reliable, and effic...