Maps now return a default value! Not really sure of the other features yet or what they mean, need to look into panic and recover more though.
March 2010
14 posts
Instead of constantly having to hit :setf go when editing your Go files in vim, just drop this into ~/.vim/ftdetect/go.vim:
autocmd BufNewFile,BufReadPost *.go set filetype=go
Everyone loves Regular Expressions, right? Instead of writing an annoying parser for our first assignment, expr, it was definitely easier to just use Go’s built in regexp package.
The easiest way is just to use regexp.MatchString:
matched, error := regexp.MatchString("[0-9]+", "1337")
This returns a boolean, matched, and an os.Error in the second variable. This whole multiple return thing is pretty crazy.
So using it in an if statement is a bit clunky if we want to do it in one line. Here’s a short example:
package main
import (
"os"
"regexp"
"fmt"
)
func main() {
if len(os.Args) == 1 {
fmt.Println("Usage: regexp [string]")
os.Exit(1)
} else if m, _ := regexp.MatchString("^[0-9]+$", os.Args[1]); m {
fmt.Println("Totally numbers")
} else {
fmt.Println("Totally not numbers")
}
}
% ./bin/regexp Usage: regexp [string] % ./bin/regexp 1234 Totally numbers % ./bin/regexp abcd Totally not numbers % ./bin/regexp 12zx34 Totally not numbersI suppose it could be two lines, but why bother? Check out the package documentation for more, and the code is here on GitHub.
It’s no surprise I like Ruby, and gofmt is a great idea I wish Ruby could enforce. Instead of forgetting to run it constantly, let’s have git run it. In your .git/hooks/pre-commit:
#!/usr/bin/env ruby
Dir["**/*.go"].each do |go|
if File.basename(go) !~ /^_/
puts "gofmt #{go}"
system("gofmt -w=true #{go} && git add #{go}")
end
end
Make sure you run chmod a+x on that hook too. Also, this will mess up any incremental commits with git add -p, but you can use git commit --no-verify to bypass the hooks if you need to.Checking out the flag package, Go’s built in command line argument parser. Here’s a simple example:
// flag.go
package main
import (
"flag"
"fmt"
)
var code *int = flag.Int("areacode", 716, "give me your codes")
func main() {
fmt.Printf("Testing out flags!\n");
flag.Parse();
fmt.Println("areacode has value ", *code);
}
# Makefile
include $(GOROOT)/src/Make.$(GOARCH)
TARG=flag
GOFILES=\
flag.go
include $(GOROOT)/src/Make.cmd
Compile and run away:
% make /Users/qrush/Progs/8g -o _go_.8 flag.go /Users/qrush/Progs/8l -o flag _go_.8 % ./flag Testing out flags! areacode has value 716 % ./flag -areacode=585 Testing out flags! areacode has value 585Mindblowing, I know. Also cool:
flag.PrintDefaults() gives a nice printout of the command line arguments with default values.From the FAQ:
…the program gofmt is a pretty-printer whose purpose is to enforce layout rules; it replaces the usual compendium of do’s and don’ts that allows interpretation. All the Go code in the repository has been run through gofmt.
usage: gofmt [flags] [path ...] -tabwidth=8: tab width -trace=false: print parse trace -r="": rewrite rule (e.g., 'α[β:len(α)] -> α[β:]') -debug=false: print debugging information -tabindent=true: indent with tabs independent of -spaces -l=false: list files whose formatting differs from gofmt's -w=false: write result to (source) file instead of stdout -spaces=true: align with spaces instead of tabs -comments=true: print comments
Took some hacking to get working since recently in go the way to convert a String into a series of Bytes changed:
There is one language change: the ability to convert a string to []byte or []int. This deprecates the strings.Bytes and strings.Runes functions. You can convert your existing sources using these gofmt commands: gofmt -r 'strings.Bytes(x) -> []byte(x)' -w file-or-directory-list gofmt -r 'strings.Runes(x) -> []int(x)' -w file-or-directory-list After running these you might need to delete unused imports of the "strings" package.Fixed now and works on my machine™, granted you put semicolons at the end of lines in the REPL.
changeset: 0:f6182e5abf5e
user: Brian Kernighan <bwk>
date: Tue Jul 18 19:05:45 1972 -0500
summary: hello, world
changeset: 1:b66d0bf8da3e
user: Brian Kernighan <bwk>
date: Sun Jan 20 01:02:03 1974 -0400
summary: convert to C
changeset: 2:ac3363d7e788
user: Brian Kernighan <research!bwk>
date: Fri Apr 01 02:02:04 1988 -0500
summary: convert to Draft-Proposed ANSI C
changeset: 3:172d32922e72
user: Brian Kernighan <bwk@research.att.com>
date: Fri Apr 01 02:03:04 1988 -0500
summary: last-minute fix: convert to ANSI C
changeset: 4:4e9a5b095532
user: Robert Griesemer <gri@golang.org>
date: Sun Mar 02 20:47:34 2008 -0800
summary: Go spec starting point.Heavily inspired by this blog post. With MacPorts installed:
sudo port install python easy_install sudo easy_install -U mercurialIn your .zshrc:
export GOROOT=[path to where you want the language installed] export GOOS=darwin export GOARCH=386 export GOBIN=[path to where you store personal bin files]Run:
source .zshrc hg clone -r release https://go.googlecode.com/hg/ $GOROOT cd $GOROOT/src ./all.bashThat should stick some binaries into your GOBIN directory. Create a helloworld.go:
package main
import fmt "fmt"
func main() {
fmt.Printf("HELLO WORLD");
}
Then run…
$ 8g helloworld.go $ 8l helloworld.8 $ ./8.out HELLO WORLD