Merge pull request #8 from qjcg/gofmt-everything

Run "go fmt" on all .go files
This commit is contained in:
Jason Thigpen
2014-12-10 09:32:34 -08:00
20 changed files with 380 additions and 379 deletions

View File

@@ -1,23 +1,23 @@
package go_koans package go_koans
func aboutAllocation() { func aboutAllocation() {
a := new(int) a := new(int)
*a = 3 *a = 3
assert(*a == __int__) // new() creates a pointer to the given type, like malloc() in C assert(*a == __int__) // new() creates a pointer to the given type, like malloc() in C
type person struct { type person struct {
name string name string
age int age int
} }
bob := new(person) bob := new(person)
assert(bob.age == __int__) // it can allocate memory for custom types as well assert(bob.age == __int__) // it can allocate memory for custom types as well
slice := make([]int, 3) slice := make([]int, 3)
assert(len(slice) == __int__) // make() creates slices of a given length assert(len(slice) == __int__) // make() creates slices of a given length
slice = make([]int, 3, __positive_int__) // but can also take an optional capacity slice = make([]int, 3, __positive_int__) // but can also take an optional capacity
assert(cap(slice) == 20) assert(cap(slice) == 20)
m := make(map[int]string) m := make(map[int]string)
assert(len(m) == __int__) // make() also creates maps assert(len(m) == __int__) // make() also creates maps
} }

View File

@@ -1,29 +1,29 @@
package go_koans package go_koans
func aboutAnonymousFunctions() { func aboutAnonymousFunctions() {
{ {
i := 1 i := 1
increment := func() { increment := func() {
i++ i++
} }
increment() increment()
assert(i == __int__) // closures function in an obvious way assert(i == __int__) // closures function in an obvious way
} }
{ {
i := 1 i := 1
increment := func(x int) { increment := func(x int) {
x++ x++
} }
increment(i) increment(i)
assert(i == __int__) // although anonymous functions need not always be closures assert(i == __int__) // although anonymous functions need not always be closures
} }
{ {
double := func(x int) int { return x * 2 } double := func(x int) int { return x * 2 }
assert(double(3) == __int__) // they can do anything our hearts desire assert(double(3) == __int__) // they can do anything our hearts desire
} }
} }

View File

@@ -1,33 +1,33 @@
package go_koans package go_koans
func aboutArrays() { func aboutArrays() {
fruits := [4]string{"apple", "orange", "mango"} fruits := [4]string{"apple", "orange", "mango"}
assert(fruits[0] == __string__) // indexes begin at 0 assert(fruits[0] == __string__) // indexes begin at 0
assert(fruits[1] == __string__) // one is indeed the loneliest number assert(fruits[1] == __string__) // one is indeed the loneliest number
assert(fruits[2] == __string__) // it takes two to ...tango? assert(fruits[2] == __string__) // it takes two to ...tango?
assert(fruits[3] == __string__) // there is no spoon, only an empty value assert(fruits[3] == __string__) // there is no spoon, only an empty value
assert(len(fruits) == __int__) // the length is what the length is assert(len(fruits) == __int__) // the length is what the length is
assert(cap(fruits) == __int__) // it can hold no more assert(cap(fruits) == __int__) // it can hold no more
assert(fruits == [4]string{}) // comparing arrays is not like comparing apples and oranges assert(fruits == [4]string{}) // comparing arrays is not like comparing apples and oranges
tasty_fruits := fruits[1:3] // defining oneself as a variation of another tasty_fruits := fruits[1:3] // defining oneself as a variation of another
assert(tasty_fruits[0] == __string__) // slices of arrays share some data assert(tasty_fruits[0] == __string__) // slices of arrays share some data
assert(tasty_fruits[1] == __string__) // albeit slightly askewed assert(tasty_fruits[1] == __string__) // albeit slightly askewed
assert(len(tasty_fruits) == __int__) // its length is manifest assert(len(tasty_fruits) == __int__) // its length is manifest
assert(cap(tasty_fruits) == __int__) // but its capacity is surprising! assert(cap(tasty_fruits) == __int__) // but its capacity is surprising!
tasty_fruits[0] = "lemon" // are their shared roots truly identical? tasty_fruits[0] = "lemon" // are their shared roots truly identical?
assert(fruits[0] == __string__) // has this element remained the same? assert(fruits[0] == __string__) // has this element remained the same?
assert(fruits[1] == __string__) // how about the second? assert(fruits[1] == __string__) // how about the second?
assert(fruits[2] == __string__) // surely one of these must have changed assert(fruits[2] == __string__) // surely one of these must have changed
assert(fruits[3] == __string__) // but who can know these things assert(fruits[3] == __string__) // but who can know these things
veggies := [...]string{"carrot", "pea"} veggies := [...]string{"carrot", "pea"}
assert(len(veggies) == __int__) // array literals need not repeat an obvious length assert(len(veggies) == __int__) // array literals need not repeat an obvious length
} }

View File

@@ -1,31 +1,31 @@
package go_koans package go_koans
func aboutBasics() { func aboutBasics() {
assert(__bool__ == true) // what is truth? assert(__bool__ == true) // what is truth?
assert(__bool__ != false) // in it there is nothing false assert(__bool__ != false) // in it there is nothing false
var i int = __int__ var i int = __int__
assert(i == 1.0000000000000000000000000000000000000) // precision is in the eye of the beholder assert(i == 1.0000000000000000000000000000000000000) // precision is in the eye of the beholder
assert(5 % 2 == __int__) assert(5%2 == __int__)
assert(5 * 2 == __int__) assert(5*2 == __int__)
assert(5 ^ 2 == __int__) assert(5^2 == __int__)
var x int var x int
assert(x == __int__) // zero values are valued in Go assert(x == __int__) // zero values are valued in Go
var f float32 var f float32
assert(f == __float32__) // for types of all types assert(f == __float32__) // for types of all types
var s string var s string
assert(s == __string__) // both typical or atypical types assert(s == __string__) // both typical or atypical types
var c struct { var c struct {
x int x int
f float32 f float32
s string s string
} }
assert(c.x == __int__) // and types within composite types assert(c.x == __int__) // and types within composite types
assert(c.f == __float32__) // which match the other types assert(c.f == __float32__) // which match the other types
assert(c.s == __string__) // in a typical way assert(c.s == __string__) // in a typical way
} }

View File

@@ -1,27 +1,27 @@
package go_koans package go_koans
func aboutChannels() { func aboutChannels() {
ch := make(chan string, 2) ch := make(chan string, 2)
assert(len(ch) == __int__) // channels are like buffers assert(len(ch) == __int__) // channels are like buffers
ch <- "foo" // i mean, "metaphors are like similes" ch <- "foo" // i mean, "metaphors are like similes"
assert(len(ch) == __int__) // they can be queried for queued items assert(len(ch) == __int__) // they can be queried for queued items
assert(<-ch == __string__) // items can be popped out of them assert(<-ch == __string__) // items can be popped out of them
assert(len(ch) == __int__) // and len() always reflects the "current" queue status assert(len(ch) == __int__) // and len() always reflects the "current" queue status
// the 'go' keyword runs a function-call in a new "goroutine" // the 'go' keyword runs a function-call in a new "goroutine"
// which executes "concurrently" with the calling "goroutine" // which executes "concurrently" with the calling "goroutine"
go func() { go func() {
// your code goes here // your code goes here
}() }()
assert(__delete_me__) // we'll need to make room for the queue, or suffer deadlocks assert(__delete_me__) // we'll need to make room for the queue, or suffer deadlocks
ch <- "bar" // this send will succeed ch <- "bar" // this send will succeed
ch <- "quux" // there's enough room for this send too ch <- "quux" // there's enough room for this send too
ch <- "extra" // but the buffer only has two slots ch <- "extra" // but the buffer only has two slots
} }

View File

@@ -3,30 +3,30 @@ package go_koans
import "bytes" import "bytes"
func aboutCommonInterfaces() { func aboutCommonInterfaces() {
{ {
in := new(bytes.Buffer) in := new(bytes.Buffer)
in.WriteString("hello world") in.WriteString("hello world")
out := new(bytes.Buffer) out := new(bytes.Buffer)
/* /*
Your code goes here. Your code goes here.
Hint, use these resources: Hint, use these resources:
$ godoc -http=:8080 $ godoc -http=:8080
$ open http://localhost:8080/pkg/io/ $ open http://localhost:8080/pkg/io/
$ open http://localhost:8080/pkg/bytes/ $ open http://localhost:8080/pkg/bytes/
*/ */
assert(out.String() == "hello world") // get data from the io.Reader to the io.Writer assert(out.String() == "hello world") // get data from the io.Reader to the io.Writer
} }
{ {
in := new(bytes.Buffer) in := new(bytes.Buffer)
in.WriteString("hello world") in.WriteString("hello world")
out := new(bytes.Buffer) out := new(bytes.Buffer)
assert(out.String() == "hello") // duplicate only a portion of the io.Reader assert(out.String() == "hello") // duplicate only a portion of the io.Reader
} }
} }

View File

@@ -1,31 +1,31 @@
package go_koans package go_koans
func isPrimeNumber(possiblePrime int) bool { func isPrimeNumber(possiblePrime int) bool {
for underPrime := 2; underPrime < possiblePrime; underPrime++ { for underPrime := 2; underPrime < possiblePrime; underPrime++ {
if possiblePrime % underPrime == 0 { if possiblePrime%underPrime == 0 {
return false return false
} }
} }
return true return true
} }
func findPrimeNumbers(channel chan int) { func findPrimeNumbers(channel chan int) {
for i := 2; /* infinite loop */ ; i++ { for i := 2; ; /* infinite loop */ i++ {
// your code goes here // your code goes here
assert(i < 100) // i is afraid of heights assert(i < 100) // i is afraid of heights
} }
} }
func aboutConcurrency() { func aboutConcurrency() {
ch := make(chan int) ch := make(chan int)
assert(__delete_me__) // concurrency can be almost trivial assert(__delete_me__) // concurrency can be almost trivial
// your code goes here // your code goes here
assert(<-ch == 2) assert(<-ch == 2)
assert(<-ch == 3) assert(<-ch == 3)
assert(<-ch == 5) assert(<-ch == 5)
assert(<-ch == 7) assert(<-ch == 7)
assert(<-ch == 11) assert(<-ch == 11)
} }

View File

@@ -3,69 +3,69 @@ package go_koans
import "fmt" import "fmt"
func aboutControlFlow() { func aboutControlFlow() {
{ {
a, b, c := 1, 2, 3 a, b, c := 1, 2, 3
assert(a == __int__) // multiple assignment assert(a == __int__) // multiple assignment
assert(b == __int__) // can make assert(b == __int__) // can make
assert(c == __int__) // life easier assert(c == __int__) // life easier
} }
var str string var str string
{ {
if 3.14 == 3 { if 3.14 == 3 {
str = "what is love?" str = "what is love?"
} else { } else {
str = "baby dont hurt me" str = "baby dont hurt me"
} }
assert(str == __string__) // no more assert(str == __string__) // no more
if length := len(str); length == 17 { if length := len(str); length == 17 {
str = "to be" str = "to be"
} else { } else {
str = "or not" str = "or not"
} }
assert(str == __string__) // that is the question assert(str == __string__) // that is the question
} }
{ {
hola1, hola2 := "ho", "la" hola1, hola2 := "ho", "la"
switch "hello" { switch "hello" {
case "hello": case "hello":
str = "hi" str = "hi"
case "world": case "world":
str = "planet" str = "planet"
case fmt.Sprintf("%s%s", hola1, hola2): case fmt.Sprintf("%s%s", hola1, hola2):
str = "senor" str = "senor"
} }
assert(str == __string__) // cases can be of any type, even arbitrary expressions assert(str == __string__) // cases can be of any type, even arbitrary expressions
switch { switch {
case false: case false:
str = "first" str = "first"
case true: case true:
str = "second" str = "second"
} }
assert(str == __string__) // in the absence of value, there is truth assert(str == __string__) // in the absence of value, there is truth
} }
{ {
n := 0 n := 0
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
n += i n += i
} }
assert(n == __int__) // for can have the structure with which we are all familiar assert(n == __int__) // for can have the structure with which we are all familiar
} }
{ {
n := 1 n := 1
for { for {
n *= 2 n *= 2
if n > 20 { if n > 20 {
break break
} }
} }
assert(n == __int__) // though omitting everything creates an infinite loop assert(n == __int__) // though omitting everything creates an infinite loop
} }
} }

View File

@@ -1,28 +1,28 @@
package go_koans package go_koans
func aboutEnumeration() { func aboutEnumeration() {
{ {
var concatenated string var concatenated string
var total int var total int
strings := []string{"hello", " world", "!"} strings := []string{"hello", " world", "!"}
for i, v := range strings { for i, v := range strings {
total += i total += i
concatenated += v concatenated += v
} }
assert(concatenated == __string__) // for loops have a modern variation assert(concatenated == __string__) // for loops have a modern variation
assert(total == __int__) // which offers both a value and an index assert(total == __int__) // which offers both a value and an index
} }
{ {
var totalLength int var totalLength int
strings := []string{"hello", " world", "!"} strings := []string{"hello", " world", "!"}
for _, v := range strings { for _, v := range strings {
totalLength += len(v) totalLength += len(v)
} }
assert(totalLength == __int__) // although we may omit either value assert(totalLength == __int__) // although we may omit either value
} }
} }

View File

@@ -4,8 +4,8 @@ import "io/ioutil"
import "strings" import "strings"
func aboutFiles() { func aboutFiles() {
filename := "about_files.go" filename := "about_files.go"
contents, _ := ioutil.ReadFile(filename) contents, _ := ioutil.ReadFile(filename)
lines := strings.Split(string(contents), "\n") lines := strings.Split(string(contents), "\n")
assert(lines[5] == __string__) // handling files is too trivial assert(lines[5] == __string__) // handling files is too trivial
} }

View File

@@ -1,48 +1,48 @@
package go_koans package go_koans
func aboutInterfaces() { func aboutInterfaces() {
bob := new(human) // bob is a kind of *human bob := new(human) // bob is a kind of *human
rspec := new(program) // rspec is a kind of *program rspec := new(program) // rspec is a kind of *program
assert(runner(bob) == __runner__) // conformed interfaces need not be declared, they are inferred assert(runner(bob) == __runner__) // conformed interfaces need not be declared, they are inferred
assert(bob.milesCompleted == 0) assert(bob.milesCompleted == 0)
assert(rspec.executionCount == 0) assert(rspec.executionCount == 0)
runTwice(bob) // bob fits the profile for a 'runner' runTwice(bob) // bob fits the profile for a 'runner'
runTwice(rspec) // rspec also fits the profile for a 'runner' runTwice(rspec) // rspec also fits the profile for a 'runner'
assert(bob.milesCompleted == __int__) // bob is affected by running in his own unique way (probably fatigue) assert(bob.milesCompleted == __int__) // bob is affected by running in his own unique way (probably fatigue)
assert(rspec.executionCount == __int__) // rspec can run completely differently than bob, thanks to interfaces assert(rspec.executionCount == __int__) // rspec can run completely differently than bob, thanks to interfaces
} }
// abstract interface and function that requires it // abstract interface and function that requires it
type runner interface { type runner interface {
run() run()
} }
func runTwice(r runner) { func runTwice(r runner) {
r.run() r.run()
r.run() r.run()
} }
// concrete type implementing the interface // concrete type implementing the interface
type human struct { type human struct {
milesCompleted int milesCompleted int
} }
func (self *human) run() { func (self *human) run() {
self.milesCompleted++ self.milesCompleted++
} }
// another concrete type implementing the interface // another concrete type implementing the interface
type program struct { type program struct {
executionCount int executionCount int
} }
func (self *program) run() { func (self *program) run() {
self.executionCount++ self.executionCount++
} }

View File

@@ -1,31 +1,31 @@
package go_koans package go_koans
func aboutMaps() { func aboutMaps() {
ages := map[string]int{ ages := map[string]int{
"bob": 10, "bob": 10,
"joe": 20, "joe": 20,
"dan": 30, "dan": 30,
} }
age := ages["bob"] age := ages["bob"]
assert(age == __int__) // map syntax is warmly familiar assert(age == __int__) // map syntax is warmly familiar
age, ok := ages["bob"] age, ok := ages["bob"]
assert(ok == __bool__) // with a handy multiple-assignment variation assert(ok == __bool__) // with a handy multiple-assignment variation
age, ok = ages["steven"] age, ok = ages["steven"]
assert(age == __int__) // the zero value is used when absent assert(age == __int__) // the zero value is used when absent
assert(ok == __boolean__) // though there are better ways to check for presence assert(ok == __boolean__) // though there are better ways to check for presence
assert(len(ages) == __int__) // length is based on keys assert(len(ages) == __int__) // length is based on keys
ages["bob"] = 99 ages["bob"] = 99
assert(ages["bob"] == __int__) // values can be changed for keys assert(ages["bob"] == __int__) // values can be changed for keys
ages["steven"] = 77 ages["steven"] = 77
assert(ages[__string__] == 77) // new ones can be added assert(ages[__string__] == 77) // new ones can be added
delete(ages, "steven") delete(ages, "steven")
age, ok = ages["steven"] age, ok = ages["steven"]
assert(ok == __boolean__) // key/value pairs can be removed assert(ok == __boolean__) // key/value pairs can be removed
} }

View File

@@ -1,14 +1,14 @@
package go_koans package go_koans
func divideFourBy(i int) int { func divideFourBy(i int) int {
return 4 / i return 4 / i
} }
const __divisor__ = 0 const __divisor__ = 0
func aboutPanics() { func aboutPanics() {
assert(__delete_me__) // panics are exceptional errors at runtime assert(__delete_me__) // panics are exceptional errors at runtime
n := divideFourBy(__divisor__) n := divideFourBy(__divisor__)
assert(n == 2) // panics are exceptional errors at runtime assert(n == 2) // panics are exceptional errors at runtime
} }

View File

@@ -1,40 +1,40 @@
package go_koans package go_koans
func aboutPointers() { func aboutPointers() {
{ {
a := 3 a := 3
b := a // 'b' is a copy of 'a' (all assignments are copy-operations) b := a // 'b' is a copy of 'a' (all assignments are copy-operations)
b++ b++
assert(a == __int__) // variables are independent of one another assert(a == __int__) // variables are independent of one another
} }
{ {
a := 3 a := 3
b := &a // 'b' is the address of 'a' b := &a // 'b' is the address of 'a'
*b = *b + 2 // de-referencing 'b' means acting like a mutable copy of 'a' *b = *b + 2 // de-referencing 'b' means acting like a mutable copy of 'a'
assert(a == __int__) // pointers seem complicated at first but are actually simple assert(a == __int__) // pointers seem complicated at first but are actually simple
} }
{ {
increment := func(i int) { increment := func(i int) {
i++ i++
} }
a := 3 a := 3
increment(a) increment(a)
assert(a == __int__) // variables are always passed by value, and so a copy is made assert(a == __int__) // variables are always passed by value, and so a copy is made
} }
{ {
realIncrement := func(i *int) { realIncrement := func(i *int) {
(*i)++ (*i)++
} }
b := 3 b := 3
realIncrement(&b) realIncrement(&b)
assert(b == __int__) // but passing a pointer allows others to mutate the value pointed to assert(b == __int__) // but passing a pointer allows others to mutate the value pointed to
} }
} }

View File

@@ -1,23 +1,23 @@
package go_koans package go_koans
func aboutSlices() { func aboutSlices() {
fruits := []string{"apple", "orange", "mango"} fruits := []string{"apple", "orange", "mango"}
assert(fruits[0] == __string__) // slices seem like arrays assert(fruits[0] == __string__) // slices seem like arrays
assert(len(fruits) == __int__) // in nearly all respects assert(len(fruits) == __int__) // in nearly all respects
tasty_fruits := fruits[1:3] // we can even slice slices tasty_fruits := fruits[1:3] // we can even slice slices
assert(tasty_fruits[0] == __string__) // slices of slices also share the underlying data assert(tasty_fruits[0] == __string__) // slices of slices also share the underlying data
pregnancy_slots := []string{"baby", "baby", "lemon"} pregnancy_slots := []string{"baby", "baby", "lemon"}
assert(cap(pregnancy_slots) == __int__) // the capacity is initially the length assert(cap(pregnancy_slots) == __int__) // the capacity is initially the length
pregnancy_slots = append(pregnancy_slots, "baby!") pregnancy_slots = append(pregnancy_slots, "baby!")
assert(len(pregnancy_slots) == __int__) // slices can be extended with append(), much like realloc in C assert(len(pregnancy_slots) == __int__) // slices can be extended with append(), much like realloc in C
assert(cap(pregnancy_slots) == __int__) // but with better optimizations assert(cap(pregnancy_slots) == __int__) // but with better optimizations
pregnancy_slots = append(pregnancy_slots, "another baby!?", "yet another, oh dear!", "they must be Catholic") pregnancy_slots = append(pregnancy_slots, "another baby!?", "yet another, oh dear!", "they must be Catholic")
assert(len(pregnancy_slots) == __int__) // append() can take N arguments to append to the slice assert(len(pregnancy_slots) == __int__) // append() can take N arguments to append to the slice
assert(cap(pregnancy_slots) == __int__) // the capacity optimizations have a guessable algorithm assert(cap(pregnancy_slots) == __int__) // the capacity optimizations have a guessable algorithm
} }

View File

@@ -3,28 +3,28 @@ package go_koans
import "fmt" import "fmt"
func aboutStrings() { func aboutStrings() {
assert("a"+__string__ == "abc") // string concatenation need not be difficult assert("a"+__string__ == "abc") // string concatenation need not be difficult
assert(len("abc") == __int__) // and bounds are thoroughly checked assert(len("abc") == __int__) // and bounds are thoroughly checked
assert("abc"[0] == __byte__) // their contents are reminiscent of C assert("abc"[0] == __byte__) // their contents are reminiscent of C
assert("smith"[2:] == __string__) // slicing may omit the end point assert("smith"[2:] == __string__) // slicing may omit the end point
assert("smith"[:4] == __string__) // or the beginning assert("smith"[:4] == __string__) // or the beginning
assert("smith"[2:4] == __string__) // or neither assert("smith"[2:4] == __string__) // or neither
assert("smith"[:] == __string__) // or both assert("smith"[:] == __string__) // or both
assert("smith" == __string__) // they can be compared directly assert("smith" == __string__) // they can be compared directly
assert("smith" < __string__) // i suppose maybe this could be useful.. someday assert("smith" < __string__) // i suppose maybe this could be useful.. someday
bytes := []byte{'a', 'b', 'c'} bytes := []byte{'a', 'b', 'c'}
assert(string(bytes) == __string__) // strings can be created from byte-slices assert(string(bytes) == __string__) // strings can be created from byte-slices
bytes[0] = 'z' bytes[0] = 'z'
assert(string(bytes) == __string__) // byte-slices can be mutated, although strings cannot assert(string(bytes) == __string__) // byte-slices can be mutated, although strings cannot
assert(fmt.Sprintf("hello %s", __string__) == "hello world") // our old friend sprintf returns assert(fmt.Sprintf("hello %s", __string__) == "hello world") // our old friend sprintf returns
assert(fmt.Sprintf("hello \"%s\"", "world") == __string__) // quoting is familiar assert(fmt.Sprintf("hello \"%s\"", "world") == __string__) // quoting is familiar
assert(fmt.Sprintf("hello %q", "world") == __string__) // although it can be done more easily assert(fmt.Sprintf("hello %q", "world") == __string__) // although it can be done more easily
assert(fmt.Sprintf("your balance: %d and %0.2f", 3, 4.5589) == __string__) // "the root of all evil" is actually a misquotation, by the way assert(fmt.Sprintf("your balance: %d and %0.2f", 3, 4.5589) == __string__) // "the root of all evil" is actually a misquotation, by the way
} }

View File

@@ -1,24 +1,24 @@
package go_koans package go_koans
func aboutStructs() { func aboutStructs() {
var bob struct { var bob struct {
name string name string
age int age int
} }
bob.name = "bob" bob.name = "bob"
bob.age = 30 bob.age = 30
assert(bob.name == __string__) // structs are collections of named variables assert(bob.name == __string__) // structs are collections of named variables
assert(bob.age == __int__) // each field has both setter and getter behavior assert(bob.age == __int__) // each field has both setter and getter behavior
type person struct { type person struct {
name string name string
age int age int
} }
var john person var john person
john.name = "bob" john.name = "bob"
john.age = __int__ john.age = __int__
assert(bob == john) // assuredly, bob is certainly not john.. yet assert(bob == john) // assuredly, bob is certainly not john.. yet
} }

View File

@@ -3,11 +3,11 @@ package go_koans
type coolNumber int type coolNumber int
func (cn coolNumber) multiplyByTwo() int { func (cn coolNumber) multiplyByTwo() int {
return int(cn) * 2 return int(cn) * 2
} }
func aboutTypes() { func aboutTypes() {
i := coolNumber(4) i := coolNumber(4)
assert(i == coolNumber(__int__)) // values can be converted between compatible types assert(i == coolNumber(__int__)) // values can be converted between compatible types
assert(i.multiplyByTwo() == __int__) // you can add methods on any type you define assert(i.multiplyByTwo() == __int__) // you can add methods on any type you define
} }

View File

@@ -3,18 +3,18 @@ package go_koans
import "strings" import "strings"
func concatNames(sep string, names ...string) string { func concatNames(sep string, names ...string) string {
return strings.Join(names, sep) // variadic parameters are really just slices return strings.Join(names, sep) // variadic parameters are really just slices
} }
func aboutVariadicFunctions() { func aboutVariadicFunctions() {
{ {
str := concatNames(" ", "bob", "billy", "fred") str := concatNames(" ", "bob", "billy", "fred")
assert(str == __string__) // several values can be passed to variadic parameters assert(str == __string__) // several values can be passed to variadic parameters
} }
{ {
names := []string{"bob", "billy", "fred"} names := []string{"bob", "billy", "fred"}
str := concatNames("-", names...) str := concatNames("-", names...)
assert(str == __string__) // or a slice can be dotted in place of all of them assert(str == __string__) // or a slice can be dotted in place of all of them
} }
} }

View File

@@ -1,61 +1,62 @@
package go_koans package go_koans
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"runtime" "runtime"
"strings" "strings"
"testing" "testing"
) )
const ( const (
__string__ string = "impossibly lame value" __string__ string = "impossibly lame value"
__int__ int = -1 __int__ int = -1
__positive_int__ int = 42 __positive_int__ int = 42
__byte__ byte = 255 __byte__ byte = 255
__bool__ bool = false // ugh __bool__ bool = false // ugh
__boolean__ bool = true // oh well __boolean__ bool = true // oh well
__float32__ float32 = -1.0 __float32__ float32 = -1.0
__delete_me__ bool = false __delete_me__ bool = false
) )
var __runner__ runner = nil var __runner__ runner = nil
func TestKoans(t *testing.T) { func TestKoans(t *testing.T) {
aboutBasics() aboutBasics()
aboutStrings() aboutStrings()
aboutArrays() aboutArrays()
aboutSlices() aboutSlices()
aboutTypes() aboutTypes()
aboutControlFlow() aboutControlFlow()
aboutEnumeration() aboutEnumeration()
aboutAnonymousFunctions() aboutAnonymousFunctions()
aboutVariadicFunctions() aboutVariadicFunctions()
aboutFiles() aboutFiles()
aboutInterfaces() aboutInterfaces()
aboutCommonInterfaces() aboutCommonInterfaces()
aboutMaps() aboutMaps()
aboutPointers() aboutPointers()
aboutStructs() aboutStructs()
aboutAllocation() aboutAllocation()
aboutChannels() aboutChannels()
aboutConcurrency() aboutConcurrency()
aboutPanics() aboutPanics()
fmt.Printf("\n%c[32;1mYou won life. Good job.\n\n", 27) fmt.Printf("\n%c[32;1mYou won life. Good job.\n\n", 27)
} }
func assert(o bool) { func assert(o bool) {
if !o { if !o {
fmt.Printf("\n%c[35m%s%c[0m\n\n", 27, __getRecentLine(), 27) fmt.Printf("\n%c[35m%s%c[0m\n\n", 27, __getRecentLine(), 27)
os.Exit(1) os.Exit(1)
} }
} }
func __getRecentLine() string { func __getRecentLine() string {
_, file, line, _ := runtime.Caller(2) _, file, line, _ := runtime.Caller(2)
buf, _ := ioutil.ReadFile(file) buf, _ := ioutil.ReadFile(file)
code := strings.TrimSpace(strings.Split(string(buf), "\n")[line-1]) code := strings.TrimSpace(strings.Split(string(buf), "\n")[line-1])
return fmt.Sprintf("%v:%d\n%s", path.Base(file), line, code) return fmt.Sprintf("%v:%d\n%s", path.Base(file), line, code)
} }