Golang中无法将n(table.Row类型变量)作为[]table.Row使用的问题

Golang中无法将n(table.Row类型变量)作为[]table.Row使用的问题 我是Go编程语言的新手。我正在尝试使用一个包,并将一个字符串切片作为参数传递。

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

关于类型Row的文档是:type Row []interface{},但我无法理解其含义。

我认为我遗漏了一些关键概念。 我应该如何处理colnames,以便能够将其传递给AppendRows函数。

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

Go Playground - The Go Programming Language

提前感谢。


更多关于Golang中无法将n(table.Row类型变量)作为[]table.Row使用的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

非常感谢您的帮助!

更多关于Golang中无法将n(table.Row类型变量)作为[]table.Row使用的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Franz: 有没有办法将类型为 []string{"a", "b", "c"} 的字符串切片“解包”成“a”、“b”、“c”?

你需要创建一个 Row 并将值复制进去。类似下面的代码应该可以工作:

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

然后你可以使用 AppendRow 来追加这一行。

n1 := table.Row{strings.Join(colnames[:], " ")}
// n1 现在是一个包含单个字段的行,其值为 "a b c"

n := table.Row{colnames}
// n 是一个包含单个字段的行,该字段包含标题的 []string 切片。
// 随后对 t.AppendRow(n) 的调用会使用与 fmt.Println 打印切片相同的默认格式来格式化 []string。

t.AppendRows([]table.Row{table.Row{colnames}})
// 基本上与上面的代码相同,但包装在额外的 []table.Row 切片层中。

你好,Franz,欢迎来到论坛!

(*table.Table).AppendRows 的函数签名是:

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

Row 前面的 [] 表示一个 Row 的“切片”。该包中还有另一个函数 (*table.Table).AppendRow,它只接受单行数据,可能就足够满足你当前的需求:

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

就像你已经发现的,Row 类型的定义也是一个切片:[]interface{}。如果把前面的“切片部分”去掉,就得到 interface{},它的意思是“任何拥有零个或多个方法的类型”(即任何类型)。所以,一个 Row 就是一个包含任意类型元素的切片。

总而言之,AppendRows 期望一个 Row 的切片,但在你的例子中,n 只是一个单独的行,所以你或者需要调用 AppendRow,或者像你在第23行所做的那样,将它包装成一个切片:

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

你好 Sean, 感谢你的详细解答。

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()
}

我理解了你给出的两个建议。遗憾的是,我并没有得到想要的结果。 有没有办法将类型为 []string{"a", "b", "c"} 的字符串切片“解包”成 “a”, “b”, “c”?

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

我目前正在学习基本概念,但这个问题悬而未决让我有点紧张,因为它看起来应该是很简单的。

非常感谢你的帮助。

问题出在AppendRows方法期望接收的是[]table.Row类型(即行切片),而你传递的是单个table.Row类型变量。根据文档,table.Row实际上是[]interface{}的类型别名。

以下是修正后的代码:

package main

import (
	"fmt"
	"os"

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

func main() {
	colnames := []string{"a", "b", "c"}
	
	// 将字符串切片转换为table.Row
	n := table.Row{"a", "b", "c"}
	
	// 或者如果你需要从colnames动态创建
	// n := make(table.Row, len(colnames))
	// for i, v := range colnames {
	//     n[i] = v
	// }
	
	l := table.Row{"d", "e", "f"}

	t := table.NewWriter()
	t.SetOutputMirror(os.Stdout)
	t.AppendHeader(l)
	
	// AppendRows需要[]table.Row,所以将单个行包装在切片中
	t.AppendRows([]table.Row{n})
	
	// 或者使用AppendRow方法添加单行
	// t.AppendRow(n)
	
	t.AppendRows([]table.Row{{"Test1", "Test2", "Test3"}})
	t.Render()
}

关键点:

  1. table.Row[]interface{}的类型别名,用于表示表格中的一行
  2. AppendRows方法需要[]table.Row参数(多行)
  3. 对于单行,可以使用AppendRow方法,或者将单行包装在切片中传递给AppendRows

如果你需要从字符串切片创建table.Row,可以这样做:

// 方法1:手动创建
n := table.Row{colnames[0], colnames[1], colnames[2]}

// 方法2:使用循环转换
n := make(table.Row, len(colnames))
for i, v := range colnames {
    n[i] = v
}

在你的原始代码中,table.Row{colnames}创建的是一个包含一个元素的table.Row,这个元素是字符串切片,而不是三个独立的单元格。

回到顶部