Below is some code with some comments to help clarify every role operators play in this.
import "testing" func TestReverse(t *testing.T) { cases := []struct { // declaration of anonymous type in, want string // fields on that type called in and want, both strings }{ {"Hello, world", "dlrow ,olleH"}, {"Hello, ไธ็", "็ไธ ,olleH"}, {"", ""}, } // composite literal initilization // note the use of := in assigning to cases, that op combines declaration and assignment into one statement for _, c := range cases { // range over cases, ignoring the index - the underscore means to discard that return value got := Reverse(c.in) // c is the current instance, access in with the familiar dot notation if got != c.want { // again, access operator on c, the current instance t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) // more access } } }
Let me know if this helps. I can try to give more resumes in colloquial language or add more information if some of the statements do not make sense. Also, fyi, if you are not familiar with the range of ranges in the collection, return k, v , where k is the index or key and v value.
EDIT: details about declaring / initializing cases
cases := []struct { in, want string }
This bit inside the first pair of braces is a structure definition. This is an anonymous type, a normal ad will look like this:
type case strcut { in string want string }
If you had something like that, then there would be a case type in the scope of this package (not exported, if you want to make it โpublicโ, so you will need a type Case instead). Instead, struct examples are anonymous. It works the same as a regular type, however, as a developer, you cannot refer to this type so that you can practically work with initializing the collection. Internally, this type is the same as any other structure with two non-laid out rows for fields. The fields are called in and want . Note that in the assignment cases := []struct , you have [] before struct , which means you are declaring a slice of this anonymous type.
This next bit is called static initialization. This is the syntax for initializing collections with types. Each of these nested bits, such as {"", ""} , is a declaration and initialization of one of these anonymous structures, which are again indicated by curly braces. In this case, you assign two empty lines in and want respectively (if you do not use names, the order will be the same as in the definition). The outer pair of braces is for cutting. If your fragment was pronounced ints or strings, then you would just get the values โโdirectly without an additional level of nesting, for example myInts := []int{5,6,7} .
{ {"Hello, world", "dlrow ,olleH"}, {"Hello, ไธ็", "็ไธ ,olleH"}, {"", ""}, }