89. GOPATH AND SETUP
•You WILL store your code in a GitHub
user folder (example: $GOPATH/src/
github.com/username/helloworld)
•This was a pain in the ass
•I was comfortable with /code /dev/
or /projects 89
90. GOPATH AND SETUP
•By Storing code on github, I was
able to share my many problems
•Going from “I’m working on this”
to “let’s collaborate”
90
91. GOPATH
•The Go toolset uses an environment variable
called GOPATH to find Go source code.
•You can set GOPATH to anything you want,
but things will be easier if it’s set in your
home directory.
91
92. Windows:
c: setx GOPATH %USERPROFILE%
OS X:
❯ echo 'export GOPATH=$HOMEn' >> ~/.bash_profile
Close the terminal, reopen it, and type the following:
❯ echo $GOPATH
GO PATH
92
94. EDITORS
•No IDE needed - any text editor will do.
•helpful features like autocomplete and
format & import on-save
•If you’re not sure what to use, I
recommend Atom — It’s free, cross-
platform, and easy to install. 94
96. YOU DON’T NEED A
FRAMEWORK!
•The standard library has tons!
•Web server
•Templates
•Database
•etc.. 96
97. YOU DON’T NEED A
FRAMEWORK!
•Many Packages work
well together
•Very modular &
Composable 97
98. STANDARD LIBRARY
Let’s be honest, you don’t want to write everything from scratch so
most programming depends on your ability to interface with existing
libraries. i.e. packages. Here are a few core packages you should
know about;
•Strings
•Input/Output (io/ioutil)
•Errors
•fmt
98
• Containers and Sort
• path/filepath
• HTTP (net/http)
• math/rand
124. NUMBERS
•Integers
(numbers without a decimal)
•Floating-Point Numbers
(numbers that contain a decimal)
• int, int8-64, uint, uint8-64, float32,64
124
125. STRINGS
•A string is a sequence of
characters
•Go strings are immutable
•Go strings are made up of
individual bytes (Usually one for each character)
125
137. GO HELP
The Go toolset has many different commands and
subcommands. You can pull up a list by typing:
go help
You now have everything you need to get started
137
138. GO FMT
•Formats your go code for you
•Awesome to do "on save"
•End of all stylistic debates
138
139. GO TEST
Writing code isn’t easy and humans make
mistakes so testing is really important, luckily, Go
includes a program that makes writing tests easier:
go test
Fun Fact: The Go compiler knows to ignore code
in files ending with _test.go
139
145. RESOURCES
•Getting Started, official golang page — https://golang.org/doc/
•Parse’s move from Ruby to Golang — http://blog.parse.com/
learn/how-we-moved-our-api-from-ruby-to-go-and-saved-our-sanity/
•Tutorial — Creating a Wiki — https://golang.org/doc/articles/
wiki/ (this was the first big tutorial that got me to build something
useful, take this one slow to get a grasps on its concepts)
•Golang — Concurrency is not Parallelism (Rob Pike), this video I
found super informative about go’s concurency and got me excited
to keep coding in Golang — https://youtu.be/cN_DpYBzKso
145
196. › go get -u
github.com/spf13/cobra/cobra
GET & INSTALL COBRA
196
197. › cobra
Cobra is a Cli library for Go that empowers applications. This
application is a tool to generate the needed files to quickly
create a Cobra application.
Usage:
cobra [command]
Available Commands:
add Add a command to a Cobra Application
COBRA
197
203. › go build
› ./tri
A longer description that spans multiple lines
and likely contains examples
and usage of using your application. For
example...
BUILD & RUN IT
203
214. // This represents the base command when called
without any subcommands
var RootCmd = &cobra.Command{
Use: "tri",
Short: "A brief description of your
application",
Long: `A longer description that spans multiple
lines and likely ... application.`,
}
CMD/ROOT.GO
214
215. // This represents the base command when called
without any subcommands
var RootCmd = &cobra.Command{
Use: "tri",
Short: "Tri is a todo application",
Long: `Tri will help you get more done in less time.
It's designed to be as simple as possible to help you
accomplish your goals.`,
}
CMD/ROOT.GO
215
223. >go run main.go
Tri will help you get more done in
less time.
It's designed to be as simple as
possible to help you accomplish
your goals.
RUN IT
223
231. var addCmd = &cobra.Command{
Use: "add",
Short: "A brief description of your command",
Long: `A longer description that spans multiple
lines and likely...`,
Run: func(cmd *cobra.Command, args []string) {
// TODO: Work your own magic here
fmt.Println("add called")
},
}
CMD/ADD.GO
231
232. var addCmd = &cobra.Command{
Use: "add",
Short: "Add a new todo",
Long: `Add will create a new todo item to the list`,
Run: func(cmd *cobra.Command, args []string) {
// TODO: Work your own magic here
fmt.Println("add called")
},
}
CMD/ADD.GO
232
234. var addCmd = &cobra.Command{
Use: "add",
Short: "Add a new todo",
Long: `Add will create a new todo
item to the list`,
Run: addRun,
}
CMD/ADD.GO
234
236. FOR x, Y := RANGE
•Provides a way to iterate over an array,
slice, string, map, or channel.
•Like Foreach or Each in other languages
•x is index/key, y is value
•_ allows you to ignore naming variables
236
238. INIT()
•Special function
•Called after package variable declarations
•Called prior to main.main()
•Each package may have multiple init()
•init() order un-guaranteed
238
239. > go run main.go add
"one two" three
one two
three
RUNNING ADD
239
244. NAMED TYPES
•Can be any known type (struct,
string, int, slice, a new type you’ve
declared, etc)
•Methods can be declared on it
•Not an alias - Explicit type 244
263. ERROR HANDLING
•Errors are not exceptional, they
are just values
•No exceptions in Go
•Errors should be handled when
they occur 263
264. ( DON’T) PANIC
•Only use when:
1. You want to shut down your program AND
2. You need a stack trace
•Packages should never call Panic (only applications)
•Do not use as pseudo-exception handling
•Only recover a panic if you know you can properly
recover from it 264
296. func init() {
// Here you will define your flags and configuration settings
// Cobra supports Persistent Flags which if defined here will
be global for your application
home, err := homedir.Dir()
if err != nil {
log.Println("Unable to detect home directory. Please set
data file using --datafile.")
}
...
CMD/ROOT.GO
296
304. › go build
› ./tri
...
Flags:
--datafile string data file to store todos (default "/
Users/spf13/.tridos.json")
-h, --help help for tri
Use "tri [command] --help" for more information about a
command.
SEE THE FLAG
304
305. › go build
› ./tri add "Add priorities"
--datafile $HOME/.next.json
› ./tri list --datafile $HOME/.next.json
[{Add priorities}]
USE THE FLAG
305
315. var priority int
...
func init() {
RootCmd.AddCommand(addCmd)
addCmd.Flags().IntVarP(&priority,
"priority", "p", 2, "Priority:1,2,3")
...
CMD/ADD.GO
315
316. var priority int
...
func init() {
RootCmd.AddCommand(addCmd)
addCmd.Flags().IntVarP(&priority,
"priority", "p", 2, "Priority:1,2,3")
...
CMD/ADD.GO
316
317. › go build
› ./tri help add
Add will create a new todo item to the list
Usage:
tri add [flags]
Flags:
-p, --priority int Priority:1,2,3 (default 2)
HELP ADD
317
381. ›./tri list --datafile
$HOME/Dropbox/Sync/tridos.json
›./tri add "Add config/ENV support"
--datafile $HOME/Dropbox/Sync/tridos.json
USING DIFFERENT DATA FILE
381
384. VIPER SUPPORTS
•YAML, TOML, JSON or HCL
•Etcd, Consul
•Config LiveReloading
•default < KeyVal < config < env < flag
•Aliases & Nested values 384
385. var cfgFile string
func init() {
cobra.OnInitialize(initConfig)
...
RootCmd.PersistentFlags().StringVar(&cfgFile,
"config", "", "config file (default is
$HOME/.tri.yaml)")
...
CMD/ROOT.GO
385
Already There
386. // Read in config file and ENV variables if set.
func initConfig() {
viper.SetConfigName(".tri")
viper.AddConfigPath("$HOME")
viper.AutomaticEnv()
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}
CMD/ROOT.GO
386
Already There
398. ›./tri list --datafile
$HOME/Dropbox/Sync/tridos.json
›./tri add "Add config/ENV support"
--datafile $HOME/Dropbox/Sync/tridos.json
USING DIFFERENT DATA FILE
398
402. // Read in config file and ENV variables if set.
func initConfig() {
viper.SetConfigName(".tri")
viper.AddConfigPath("$HOME")
viper.AutomaticEnv()
viper.SetEnvPrefix("tri")
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
CMD/ROOT.GO
402