diff --git a/about_allocation.go b/about_allocation.go index 3d09ee8..6785571 100644 --- a/about_allocation.go +++ b/about_allocation.go @@ -1,23 +1,23 @@ package go_koans func aboutAllocation() { - a := new(int) - *a = 3 - assert(*a == __int__) // new() creates a pointer to the given type, like malloc() in C + a := new(int) + *a = 3 + assert(*a == __int__) // new() creates a pointer to the given type, like malloc() in C - type person struct { - name string - age int - } - bob := new(person) - assert(bob.age == __int__) // it can allocate memory for custom types as well + type person struct { + name string + age int + } + bob := new(person) + assert(bob.age == __int__) // it can allocate memory for custom types as well - slice := make([]int, 3) - assert(len(slice) == __int__) // make() creates slices of a given length + slice := make([]int, 3) + assert(len(slice) == __int__) // make() creates slices of a given length - slice = make([]int, 3, __positive_int__) // but can also take an optional capacity - assert(cap(slice) == 20) + slice = make([]int, 3, __positive_int__) // but can also take an optional capacity + assert(cap(slice) == 20) - m := make(map[int]string) - assert(len(m) == __int__) // make() also creates maps + m := make(map[int]string) + assert(len(m) == __int__) // make() also creates maps } diff --git a/about_anonymous_functions.go b/about_anonymous_functions.go index c3cc5ad..4ef5aed 100644 --- a/about_anonymous_functions.go +++ b/about_anonymous_functions.go @@ -1,29 +1,29 @@ package go_koans func aboutAnonymousFunctions() { - { - i := 1 - increment := func() { - i++ - } - increment() + { + i := 1 + increment := func() { + i++ + } + increment() - assert(i == __int__) // closures function in an obvious way - } + assert(i == __int__) // closures function in an obvious way + } - { - i := 1 - increment := func(x int) { - x++ - } - increment(i) + { + i := 1 + increment := func(x int) { + x++ + } + 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 + } } diff --git a/about_arrays.go b/about_arrays.go index 8c635bc..de270c7 100644 --- a/about_arrays.go +++ b/about_arrays.go @@ -1,33 +1,33 @@ package go_koans func aboutArrays() { - fruits := [4]string{"apple", "orange", "mango"} + fruits := [4]string{"apple", "orange", "mango"} - assert(fruits[0] == __string__) // indexes begin at 0 - assert(fruits[1] == __string__) // one is indeed the loneliest number - assert(fruits[2] == __string__) // it takes two to ...tango? - assert(fruits[3] == __string__) // there is no spoon, only an empty value + assert(fruits[0] == __string__) // indexes begin at 0 + assert(fruits[1] == __string__) // one is indeed the loneliest number + assert(fruits[2] == __string__) // it takes two to ...tango? + assert(fruits[3] == __string__) // there is no spoon, only an empty value - assert(len(fruits) == __int__) // the length is what the length is - assert(cap(fruits) == __int__) // it can hold no more + assert(len(fruits) == __int__) // the length is what the length is + 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 - assert(tasty_fruits[0] == __string__) // slices of arrays share some data - assert(tasty_fruits[1] == __string__) // albeit slightly askewed + 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[1] == __string__) // albeit slightly askewed - assert(len(tasty_fruits) == __int__) // its length is manifest - assert(cap(tasty_fruits) == __int__) // but its capacity is surprising! + assert(len(tasty_fruits) == __int__) // its length is manifest + 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[1] == __string__) // how about the second? - assert(fruits[2] == __string__) // surely one of these must have changed - assert(fruits[3] == __string__) // but who can know these things + assert(fruits[0] == __string__) // has this element remained the same? + assert(fruits[1] == __string__) // how about the second? + assert(fruits[2] == __string__) // surely one of these must have changed + 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 } diff --git a/about_basics.go b/about_basics.go index 8055460..85e1f70 100644 --- a/about_basics.go +++ b/about_basics.go @@ -1,31 +1,31 @@ package go_koans func aboutBasics() { - assert(__bool__ == true) // what is truth? - assert(__bool__ != false) // in it there is nothing false + assert(__bool__ == true) // what is truth? + assert(__bool__ != false) // in it there is nothing false - var i int = __int__ - assert(i == 1.0000000000000000000000000000000000000) // precision is in the eye of the beholder + var i int = __int__ + 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 - assert(x == __int__) // zero values are valued in Go + var x int + assert(x == __int__) // zero values are valued in Go - var f float32 - assert(f == __float32__) // for types of all types + var f float32 + assert(f == __float32__) // for types of all types - var s string - assert(s == __string__) // both typical or atypical types + var s string + assert(s == __string__) // both typical or atypical types - var c struct { - x int - f float32 - s string - } - assert(c.x == __int__) // and types within composite types - assert(c.f == __float32__) // which match the other types - assert(c.s == __string__) // in a typical way + var c struct { + x int + f float32 + s string + } + assert(c.x == __int__) // and types within composite types + assert(c.f == __float32__) // which match the other types + assert(c.s == __string__) // in a typical way } diff --git a/about_channels.go b/about_channels.go index e183462..00561b2 100644 --- a/about_channels.go +++ b/about_channels.go @@ -1,27 +1,27 @@ package go_koans 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" - // which executes "concurrently" with the calling "goroutine" - go func() { - // your code goes here - }() + // the 'go' keyword runs a function-call in a new "goroutine" + // which executes "concurrently" with the calling "goroutine" + go func() { + // 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 <- "quux" // there's enough room for this send too - ch <- "extra" // but the buffer only has two slots + ch <- "bar" // this send will succeed + ch <- "quux" // there's enough room for this send too + ch <- "extra" // but the buffer only has two slots } diff --git a/about_common_interfaces.go b/about_common_interfaces.go index 80eb6b6..d987e96 100644 --- a/about_common_interfaces.go +++ b/about_common_interfaces.go @@ -3,30 +3,30 @@ package go_koans import "bytes" func aboutCommonInterfaces() { - { - in := new(bytes.Buffer) - in.WriteString("hello world") + { + in := new(bytes.Buffer) + in.WriteString("hello world") - out := new(bytes.Buffer) + out := new(bytes.Buffer) - /* - Your code goes here. - Hint, use these resources: + /* + Your code goes here. + Hint, use these resources: - $ godoc -http=:8080 - $ open http://localhost:8080/pkg/io/ - $ open http://localhost:8080/pkg/bytes/ - */ + $ godoc -http=:8080 + $ open http://localhost:8080/pkg/io/ + $ 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.WriteString("hello world") + { + in := new(bytes.Buffer) + 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 + } } diff --git a/about_concurrency.go b/about_concurrency.go index e455a34..2921e6b 100644 --- a/about_concurrency.go +++ b/about_concurrency.go @@ -1,31 +1,31 @@ package go_koans func isPrimeNumber(possiblePrime int) bool { - for underPrime := 2; underPrime < possiblePrime; underPrime++ { - if possiblePrime % underPrime == 0 { - return false - } - } - return true + for underPrime := 2; underPrime < possiblePrime; underPrime++ { + if possiblePrime%underPrime == 0 { + return false + } + } + return true } func findPrimeNumbers(channel chan int) { - for i := 2; /* infinite loop */ ; i++ { - // your code goes here + for i := 2; ; /* infinite loop */ i++ { + // your code goes here - assert(i < 100) // i is afraid of heights - } + assert(i < 100) // i is afraid of heights + } } func aboutConcurrency() { - ch := make(chan int) + ch := make(chan int) - assert(__delete_me__) // concurrency can be almost trivial - // your code goes here + assert(__delete_me__) // concurrency can be almost trivial + // your code goes here - assert(<-ch == 2) - assert(<-ch == 3) - assert(<-ch == 5) - assert(<-ch == 7) - assert(<-ch == 11) + assert(<-ch == 2) + assert(<-ch == 3) + assert(<-ch == 5) + assert(<-ch == 7) + assert(<-ch == 11) } diff --git a/about_control_flow.go b/about_control_flow.go index 10a0b0e..34cca53 100644 --- a/about_control_flow.go +++ b/about_control_flow.go @@ -3,69 +3,69 @@ package go_koans import "fmt" func aboutControlFlow() { - { - a, b, c := 1, 2, 3 - assert(a == __int__) // multiple assignment - assert(b == __int__) // can make - assert(c == __int__) // life easier - } + { + a, b, c := 1, 2, 3 + assert(a == __int__) // multiple assignment + assert(b == __int__) // can make + assert(c == __int__) // life easier + } - var str string + var str string - { - if 3.14 == 3 { - str = "what is love?" - } else { - str = "baby dont hurt me" - } - assert(str == __string__) // no more + { + if 3.14 == 3 { + str = "what is love?" + } else { + str = "baby dont hurt me" + } + assert(str == __string__) // no more - if length := len(str); length == 17 { - str = "to be" - } else { - str = "or not" - } - assert(str == __string__) // that is the question - } + if length := len(str); length == 17 { + str = "to be" + } else { + str = "or not" + } + assert(str == __string__) // that is the question + } - { - hola1, hola2 := "ho", "la" + { + hola1, hola2 := "ho", "la" - switch "hello" { - case "hello": - str = "hi" - case "world": - str = "planet" - case fmt.Sprintf("%s%s", hola1, hola2): - str = "senor" - } - assert(str == __string__) // cases can be of any type, even arbitrary expressions + switch "hello" { + case "hello": + str = "hi" + case "world": + str = "planet" + case fmt.Sprintf("%s%s", hola1, hola2): + str = "senor" + } + assert(str == __string__) // cases can be of any type, even arbitrary expressions - switch { - case false: - str = "first" - case true: - str = "second" - } - assert(str == __string__) // in the absence of value, there is truth - } + switch { + case false: + str = "first" + case true: + str = "second" + } + assert(str == __string__) // in the absence of value, there is truth + } - { - n := 0 - for i := 0; i < 5; i++ { - n += i - } - assert(n == __int__) // for can have the structure with which we are all familiar - } + { + n := 0 + for i := 0; i < 5; i++ { + n += i + } + assert(n == __int__) // for can have the structure with which we are all familiar + } - { - n := 1 - for { - n *= 2 - if n > 20 { - break - } - } - assert(n == __int__) // though omitting everything creates an infinite loop - } + { + n := 1 + for { + n *= 2 + if n > 20 { + break + } + } + assert(n == __int__) // though omitting everything creates an infinite loop + } } diff --git a/about_enumeration.go b/about_enumeration.go index c6d4c2f..b474bd2 100644 --- a/about_enumeration.go +++ b/about_enumeration.go @@ -1,28 +1,28 @@ package go_koans func aboutEnumeration() { - { - var concatenated string - var total int + { + var concatenated string + var total int - strings := []string{"hello", " world", "!"} - for i, v := range strings { - total += i - concatenated += v - } + strings := []string{"hello", " world", "!"} + for i, v := range strings { + total += i + concatenated += v + } - assert(concatenated == __string__) // for loops have a modern variation - assert(total == __int__) // which offers both a value and an index - } + assert(concatenated == __string__) // for loops have a modern variation + assert(total == __int__) // which offers both a value and an index + } - { - var totalLength int + { + var totalLength int - strings := []string{"hello", " world", "!"} - for _, v := range strings { - totalLength += len(v) - } + strings := []string{"hello", " world", "!"} + for _, v := range strings { + totalLength += len(v) + } - assert(totalLength == __int__) // although we may omit either value - } + assert(totalLength == __int__) // although we may omit either value + } } diff --git a/about_files.go b/about_files.go index 811c6dd..cecb028 100644 --- a/about_files.go +++ b/about_files.go @@ -4,8 +4,8 @@ import "io/ioutil" import "strings" func aboutFiles() { - filename := "about_files.go" - contents, _ := ioutil.ReadFile(filename) - lines := strings.Split(string(contents), "\n") - assert(lines[5] == __string__) // handling files is too trivial + filename := "about_files.go" + contents, _ := ioutil.ReadFile(filename) + lines := strings.Split(string(contents), "\n") + assert(lines[5] == __string__) // handling files is too trivial } diff --git a/about_interfaces.go b/about_interfaces.go index c6d4e8a..cf264b2 100644 --- a/about_interfaces.go +++ b/about_interfaces.go @@ -1,48 +1,48 @@ package go_koans func aboutInterfaces() { - bob := new(human) // bob is a kind of *human - rspec := new(program) // rspec is a kind of *program + bob := new(human) // bob is a kind of *human + 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(rspec.executionCount == 0) + assert(bob.milesCompleted == 0) + assert(rspec.executionCount == 0) - runTwice(bob) // bob fits the profile for a 'runner' - runTwice(rspec) // rspec also 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' - 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(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 } // abstract interface and function that requires it type runner interface { - run() + run() } func runTwice(r runner) { - r.run() - r.run() + r.run() + r.run() } // concrete type implementing the interface type human struct { - milesCompleted int + milesCompleted int } func (self *human) run() { - self.milesCompleted++ + self.milesCompleted++ } // another concrete type implementing the interface type program struct { - executionCount int + executionCount int } func (self *program) run() { - self.executionCount++ + self.executionCount++ } diff --git a/about_maps.go b/about_maps.go index 6239582..32abc1d 100644 --- a/about_maps.go +++ b/about_maps.go @@ -1,31 +1,31 @@ package go_koans func aboutMaps() { - ages := map[string]int{ - "bob": 10, - "joe": 20, - "dan": 30, - } + ages := map[string]int{ + "bob": 10, + "joe": 20, + "dan": 30, + } - age := ages["bob"] - assert(age == __int__) // map syntax is warmly familiar + age := ages["bob"] + assert(age == __int__) // map syntax is warmly familiar - age, ok := ages["bob"] - assert(ok == __bool__) // with a handy multiple-assignment variation + age, ok := ages["bob"] + assert(ok == __bool__) // with a handy multiple-assignment variation - age, ok = ages["steven"] - assert(age == __int__) // the zero value is used when absent - assert(ok == __boolean__) // though there are better ways to check for presence + age, ok = ages["steven"] + assert(age == __int__) // the zero value is used when absent + 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 - assert(ages["bob"] == __int__) // values can be changed for keys + ages["bob"] = 99 + assert(ages["bob"] == __int__) // values can be changed for keys - ages["steven"] = 77 - assert(ages[__string__] == 77) // new ones can be added + ages["steven"] = 77 + assert(ages[__string__] == 77) // new ones can be added - delete(ages, "steven") - age, ok = ages["steven"] - assert(ok == __boolean__) // key/value pairs can be removed + delete(ages, "steven") + age, ok = ages["steven"] + assert(ok == __boolean__) // key/value pairs can be removed } diff --git a/about_panics.go b/about_panics.go index 55088ef..0b77485 100644 --- a/about_panics.go +++ b/about_panics.go @@ -1,14 +1,14 @@ package go_koans func divideFourBy(i int) int { - return 4 / i + return 4 / i } const __divisor__ = 0 func aboutPanics() { - assert(__delete_me__) // panics are exceptional errors at runtime + assert(__delete_me__) // panics are exceptional errors at runtime - n := divideFourBy(__divisor__) - assert(n == 2) // panics are exceptional errors at runtime + n := divideFourBy(__divisor__) + assert(n == 2) // panics are exceptional errors at runtime } diff --git a/about_pointers.go b/about_pointers.go index 2761254..140e4a3 100644 --- a/about_pointers.go +++ b/about_pointers.go @@ -1,40 +1,40 @@ package go_koans func aboutPointers() { - { - a := 3 - b := a // 'b' is a copy of 'a' (all assignments are copy-operations) + { + a := 3 + 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 - b := &a // 'b' is the address of 'a' + { + a := 3 + b := &a // 'b' is the address 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 - } + *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 + } - { - increment := func(i int) { - i++ - } + { + increment := func(i int) { + i++ + } - a := 3 - increment(a) - assert(a == __int__) // variables are always passed by value, and so a copy is made - } + a := 3 + increment(a) + assert(a == __int__) // variables are always passed by value, and so a copy is made + } - { - realIncrement := func(i *int) { - (*i)++ - } + { + realIncrement := func(i *int) { + (*i)++ + } - b := 3 - realIncrement(&b) - assert(b == __int__) // but passing a pointer allows others to mutate the value pointed to - } + b := 3 + realIncrement(&b) + assert(b == __int__) // but passing a pointer allows others to mutate the value pointed to + } } diff --git a/about_slices.go b/about_slices.go index a3fba29..317d847 100644 --- a/about_slices.go +++ b/about_slices.go @@ -1,23 +1,23 @@ package go_koans func aboutSlices() { - fruits := []string{"apple", "orange", "mango"} + fruits := []string{"apple", "orange", "mango"} - assert(fruits[0] == __string__) // slices seem like arrays - assert(len(fruits) == __int__) // in nearly all respects + assert(fruits[0] == __string__) // slices seem like arrays + assert(len(fruits) == __int__) // in nearly all respects - tasty_fruits := fruits[1:3] // we can even slice slices - assert(tasty_fruits[0] == __string__) // slices of slices also share the underlying data + tasty_fruits := fruits[1:3] // we can even slice slices + assert(tasty_fruits[0] == __string__) // slices of slices also share the underlying data - pregnancy_slots := []string{"baby", "baby", "lemon"} - assert(cap(pregnancy_slots) == __int__) // the capacity is initially the length + pregnancy_slots := []string{"baby", "baby", "lemon"} + assert(cap(pregnancy_slots) == __int__) // the capacity is initially the length - pregnancy_slots = append(pregnancy_slots, "baby!") - 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 + pregnancy_slots = append(pregnancy_slots, "baby!") + 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 - 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(cap(pregnancy_slots) == __int__) // the capacity optimizations have a guessable algorithm + 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 } diff --git a/about_strings.go b/about_strings.go index 83fdc17..41b07f5 100644 --- a/about_strings.go +++ b/about_strings.go @@ -3,28 +3,28 @@ package go_koans import "fmt" func aboutStrings() { - assert("a"+__string__ == "abc") // string concatenation need not be difficult - assert(len("abc") == __int__) // and bounds are thoroughly checked + assert("a"+__string__ == "abc") // string concatenation need not be difficult + 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"[:4] == __string__) // or the beginning - assert("smith"[2:4] == __string__) // or neither - assert("smith"[:] == __string__) // or both + assert("smith"[2:] == __string__) // slicing may omit the end point + assert("smith"[:4] == __string__) // or the beginning + assert("smith"[2:4] == __string__) // or neither + assert("smith"[:] == __string__) // or both - assert("smith" == __string__) // they can be compared directly - assert("smith" < __string__) // i suppose maybe this could be useful.. someday + assert("smith" == __string__) // they can be compared directly + assert("smith" < __string__) // i suppose maybe this could be useful.. someday - bytes := []byte{'a', 'b', 'c'} - assert(string(bytes) == __string__) // strings can be created from byte-slices + bytes := []byte{'a', 'b', 'c'} + assert(string(bytes) == __string__) // strings can be created from byte-slices - bytes[0] = 'z' - assert(string(bytes) == __string__) // byte-slices can be mutated, although strings cannot + bytes[0] = 'z' + 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\"", "world") == __string__) // quoting is familiar - assert(fmt.Sprintf("hello %q", "world") == __string__) // although it can be done more easily + 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 %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 } diff --git a/about_structs.go b/about_structs.go index 5298102..95ec486 100644 --- a/about_structs.go +++ b/about_structs.go @@ -1,24 +1,24 @@ package go_koans func aboutStructs() { - var bob struct { - name string - age int - } - bob.name = "bob" - bob.age = 30 + var bob struct { + name string + age int + } + bob.name = "bob" + bob.age = 30 - assert(bob.name == __string__) // structs are collections of named variables - assert(bob.age == __int__) // each field has both setter and getter behavior + assert(bob.name == __string__) // structs are collections of named variables + assert(bob.age == __int__) // each field has both setter and getter behavior - type person struct { - name string - age int - } + type person struct { + name string + age int + } - var john person - john.name = "bob" - john.age = __int__ + var john person + john.name = "bob" + john.age = __int__ - assert(bob == john) // assuredly, bob is certainly not john.. yet + assert(bob == john) // assuredly, bob is certainly not john.. yet } diff --git a/about_types.go b/about_types.go index e37176a..4d2849a 100644 --- a/about_types.go +++ b/about_types.go @@ -3,11 +3,11 @@ package go_koans type coolNumber int func (cn coolNumber) multiplyByTwo() int { - return int(cn) * 2 + return int(cn) * 2 } func aboutTypes() { - i := coolNumber(4) - assert(i == coolNumber(__int__)) // values can be converted between compatible types - assert(i.multiplyByTwo() == __int__) // you can add methods on any type you define + i := coolNumber(4) + assert(i == coolNumber(__int__)) // values can be converted between compatible types + assert(i.multiplyByTwo() == __int__) // you can add methods on any type you define } diff --git a/about_variadic_functions.go b/about_variadic_functions.go index cb78278..4720457 100644 --- a/about_variadic_functions.go +++ b/about_variadic_functions.go @@ -3,18 +3,18 @@ package go_koans import "strings" 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() { - { - str := concatNames(" ", "bob", "billy", "fred") - assert(str == __string__) // several values can be passed to variadic parameters - } + { + str := concatNames(" ", "bob", "billy", "fred") + assert(str == __string__) // several values can be passed to variadic parameters + } - { - names := []string{"bob", "billy", "fred"} - str := concatNames("-", names...) - assert(str == __string__) // or a slice can be dotted in place of all of them - } + { + names := []string{"bob", "billy", "fred"} + str := concatNames("-", names...) + assert(str == __string__) // or a slice can be dotted in place of all of them + } } diff --git a/setup_koans_test.go b/setup_koans_test.go index 26c3bc1..d0c133f 100644 --- a/setup_koans_test.go +++ b/setup_koans_test.go @@ -1,61 +1,62 @@ package go_koans import ( - "fmt" - "io/ioutil" - "os" - "path" - "runtime" - "strings" - "testing" + "fmt" + "io/ioutil" + "os" + "path" + "runtime" + "strings" + "testing" ) const ( - __string__ string = "impossibly lame value" - __int__ int = -1 - __positive_int__ int = 42 - __byte__ byte = 255 - __bool__ bool = false // ugh - __boolean__ bool = true // oh well - __float32__ float32 = -1.0 - __delete_me__ bool = false + __string__ string = "impossibly lame value" + __int__ int = -1 + __positive_int__ int = 42 + __byte__ byte = 255 + __bool__ bool = false // ugh + __boolean__ bool = true // oh well + __float32__ float32 = -1.0 + __delete_me__ bool = false ) + var __runner__ runner = nil func TestKoans(t *testing.T) { - aboutBasics() - aboutStrings() - aboutArrays() - aboutSlices() - aboutTypes() - aboutControlFlow() - aboutEnumeration() - aboutAnonymousFunctions() - aboutVariadicFunctions() - aboutFiles() - aboutInterfaces() - aboutCommonInterfaces() - aboutMaps() - aboutPointers() - aboutStructs() - aboutAllocation() - aboutChannels() - aboutConcurrency() - aboutPanics() + aboutBasics() + aboutStrings() + aboutArrays() + aboutSlices() + aboutTypes() + aboutControlFlow() + aboutEnumeration() + aboutAnonymousFunctions() + aboutVariadicFunctions() + aboutFiles() + aboutInterfaces() + aboutCommonInterfaces() + aboutMaps() + aboutPointers() + aboutStructs() + aboutAllocation() + aboutChannels() + aboutConcurrency() + 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) { - if !o { - fmt.Printf("\n%c[35m%s%c[0m\n\n", 27, __getRecentLine(), 27) - os.Exit(1) - } + if !o { + fmt.Printf("\n%c[35m%s%c[0m\n\n", 27, __getRecentLine(), 27) + os.Exit(1) + } } func __getRecentLine() string { - _, file, line, _ := runtime.Caller(2) - buf, _ := ioutil.ReadFile(file) - code := strings.TrimSpace(strings.Split(string(buf), "\n")[line-1]) - return fmt.Sprintf("%v:%d\n%s", path.Base(file), line, code) + _, file, line, _ := runtime.Caller(2) + buf, _ := ioutil.ReadFile(file) + code := strings.TrimSpace(strings.Split(string(buf), "\n")[line-1]) + return fmt.Sprintf("%v:%d\n%s", path.Base(file), line, code) }