Cannot use n (variable of type table.Row) as []table.Row

Hi
I am new to the Go programming language. I am trying to use a package and passing a slice of strings as parameters.

package main

import (
	"fmt"
	"os"
	"reflect"

	"github.com/jedib0t/go-pretty/v6/table"
)

func main() {
	colnames := []string{"a", "b", "c"}
	fmt.Println(reflect.TypeOf(colnames))

	n := table.Row{colnames}
	//n1 := table.Row{strings.Join(colnames[:], " ")}
	l := table.Row{"d", "e", "f"}

	t := table.NewWriter()
	t.SetOutputMirror(os.Stdout)
	t.AppendHeader(l)
	t.AppendRows(n)
	t.AppendRows([]table.Row{{"Test1", "Test2", "Test3"}})
	t.Render()
}
./prog.go:24:15: cannot use n (variable of type table.Row) as []table.Row value in argument to t.AppendRows

The documentation on the Type Row is: type Row []interface{} but i cant make any sense of it.

I think I am missing some key concepts.
What should I do with colnames in order to be able to pass this down to the append Rows function.

https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/table#Row

Thanks in advance,
Franz

Hi, Franz, and welcome to the forum!

The function signature of (*table.Table).AppendRows is:

func (t *Table) AppendRows(rows []Row, config ...RowConfig)

And the [] pair in front of Row means a “slice” of Rows. There’s another function in that package, (*table.Table).AppendRow which only takes a single row which might be good enough for what you’re trying to do right now:

func (t *Table) AppendRow(row Row, config ...RowConfig)

Like you already found, the definition of the Row type is also a slice: []interface{}. If you pop the “slice part” off the front, you get interface{} which means “any type that has zero or more methods” (i.e. anything). So a Row is a slice of anything.

All in all, AppendRows expects a slice of Rows, but n in your example is just a single row, so you either have to call AppendRow instead or wrap it into a slice like you did on line 23:

t.AppendRows([]table.Row{n})
1 Like

Hi Sean,
thanks for your detailled answer.

package main

import (
	"fmt"
	"os"
	"reflect"
	"strings"

	"github.com/jedib0t/go-pretty/v6/table"
)

func main() {
	colnames := []string{"a", "b", "c"}
	fmt.Println(reflect.TypeOf(colnames))

	n := table.Row{colnames}
	n1 := table.Row{strings.Join(colnames[:], " ")}
	l := table.Row{"d", "e", "f"}

	t := table.NewWriter()
	t.SetOutputMirror(os.Stdout)
	t.AppendHeader(l)
	t.AppendRow(l)
	//t.AppendRows([]l)
	t.AppendRows([]table.Row{{"Test1", "Test2", "Test3"}})
	t.AppendRow(n1)
	t.AppendRow(n)
	t.AppendRows([]table.Row{table.Row{colnames}})
	t.Render()
}

I did understand both of your suggestions. Unfortunatelly I didnt get the desired result.
Is there a way of “unpacking” the slice of Strings from type []string{"a", "b", "c"} to “a”, “b”, “c”?

±--------±------±------+
| D | E | F |
±--------±------±------+
| d | e | f |
| Test1 | Test2 | Test3 |
| a b c | | |
| [a b c] | | |
| [a b c] | | |
±--------±------±------+

I’m currently learning the basic concepts, but the fact that it’s unsolved makes me kind of nervous as it seems to be trivial.

I really appreciate your effort.

You have to create a Row and copy the values into it. Something like this should work:

row := make(table.Row, len(colnames))
for i, colname := range colnames {
    row[i] = colname
}

Then you append the row with AppendRow.

n1 := table.Row{strings.Join(colnames[:], " ")}
// n1 is now a row with a single field whose value is "a b c"

n := table.Row{colnames}
// n is a row with a single field which contains the []string slice of headers.
// The later call to t.AppendRow(n) formats the []string with the same default
// formatting that fmt.Println would print a slice.

t.AppendRows([]table.Row{table.Row{colnames}})
// Basically the same thing as the code above, but wrapped in an extra layer of
// []table.Row slice.
1 Like

Thanks a lot for help!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.