for
to make a Sum
function. Sum
will take an array of numbers and return the total.sum_test.go
and insert the following:numbers := [5]int{1, 2, 3, 4, 5}
numbers := [...]int{1, 2, 3, 4, 5}
%v
placeholder to print the "default" format, which works well for arrays.go mod init main
you will be presented with an error _testmain.go:13:2: cannot import "main"
. This is because according to common practice, package main will only contain integration of other packages and not unit-testable code and hence Go will not allow you to import a package with name main
.go.mod
to any other name.go test
the compiler will fail with the familiar ./sum_test.go:10:15: undefined: Sum
error. Now we can proceed with writing the actual method to be tested.sum.go
sum_test.go:13: got 0 want 15 given, [1 2 3 4 5]
array[index]
syntax. In this case, we are using for
to iterate 5 times to work through the array and add each item onto sum
.range
lets you iterate over an array. On each iteration, range
returns two values - the index and the value. We are choosing to ignore the index value by using _
blank identifier.[4]int
into a function that expects [5]int
, it won't compile. They are different types so it's just the same as trying to pass a string
into a function that wants an int
.mySlice := []int{1,2,3}
rather than myArray := [3]int{1,2,3}
./sum_test.go:22:13: cannot use numbers (type []int) as type [5]int in argument to Sum
Sum
to be a slice rather than an array. When we do this, we will potentially ruin someone's day because our other test will no longer compile!Sum
- all we did was replace arrays with slices, so no extra changes are required. Remember that we must not neglect our test code in the refactoring stage - we can further improve our Sum
tests.go test -cover
SumAll
which will take a varying number of slices, returning a new slice containing the totals for each slice passed in.SumAll([]int{1,2}, []int{0,9})
would return []int{3, 9}
SumAll([]int{1,1,1})
would return []int{3}
./sum_test.go:23:9: undefined: SumAll
SumAll
according to what our test wants../sum_test.go:26:9: invalid operation: got != want (slice can only be compared to nil)
got
and want
slice and check their values but for convenience sake, we can use reflect.DeepEqual
which is useful for seeing if any two variables are the same.import reflect
in the top of your file to have access to DeepEqual
)reflect.DeepEqual
is not "type safe" - the code will compile even if you did something a bit silly. To see this in action, temporarily change the test to:slice
with a string
. This makes no sense, but the test compiles! So while using reflect.DeepEqual
is a convenient way of comparing slices (and other things) you must be careful when using it.sum_test.go:30: got [] want [3 9]
Sum
function, then add it to the slice we will returnmake
allows you to create a slice with a starting capacity of the len
of the numbersToSum
we need to work through.mySlice[N]
to get the value out or assign it a new value with =
mySlice[10] = 1
you will get a runtime error.append
function which takes a slice and a new value, then returns a new slice with all the items in it.sums
and append to it the result of Sum
as we work through the varargs.SumAll
to SumAllTails
, where it will calculate the totals of the "tails" of each slice. The tail of a collection is all items in the collection except the first one (the "head")../sum_test.go:26:9: undefined: SumAllTails
SumAllTails
and re-run the testsum_test.go:30: got [3 9] want [2 9]
slice[low:high]
. If you omit the value on one of the sides of the :
it captures everything to that side of it. In our case, we are saying "take from 1 to the end" with numbers[1:]
. You may wish to spend some time writing other tests around slices and experiment with the slice operator to get more familiar with it.myEmptySlice[1:]
?checkSums(t, got, "dave")
the compiler will stop them in their tracks.append
len
to get the length of an array or slicereflect.DeepEqual
and why it's useful but can reduce the type-safety of your code[][]string
if you need to.