Golang语法问题:接口数组的使用疑问
Golang语法问题:接口数组的使用疑问 在我编写的程序中,我需要向GTK Treeview添加一个新行,代码如下:
// 将视频添加到列表
iter := listStore.Append()
err := listStore.Set(iter, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
[]interface{}{thumbnail,
video.SubscriptionName,
video.Added.Format(constDateLayout),
video.Title,
progress,
backgroundColor,
video.ID,
duration,
progressText,
foregroundColor})
这段代码运行正常,但我很好奇为什么最后一个数组([]interface{}{…})中多了一组花括号?如果你将其与第二个参数([]int{…})进行比较,后者只有一组花括号。显然,我只是找到了一段能工作的代码并复制粘贴了它。但现在我很好奇它为什么能工作……
【编辑】加粗(使用**)似乎不起作用……?
更多关于Golang语法问题:接口数组的使用疑问的实战教程也可以访问 https://www.itying.com/category-94-b0.html
[]int{0, 1, 2} 表示一个 int 类型的切片 ([]),并用 {0, 1, 2} 初始化它。
[]interface{}{0, 1, 2} 表示一个 interface{} 类型的切片,并用 {0, 1, 2} 初始化它。
Go 语言支持匿名类型。你也可以这样写:
stringers := []interface { String() string }{
new(bytes.Buffer),
big.NewFloat(123.456),
}
更多关于Golang语法问题:接口数组的使用疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
[]int{0, 1, 2}表示一个int类型的切片([]),并用{0, 1, 2}初始化它。
[]interface{}{0, 1, 2}表示一个interface{}类型的切片,并用{0, 1, 2}初始化它。
这部分我理解了…
Go 可以有匿名类型。你也可以这样写:
stringers := []interface { String() string }{ new(bytes.Buffer), big.NewFloat(123.456), }
这个我不完全理解,花括号是只适用于接口的东西吗?我的意思是,你不能写 int{}{0,1,2,3},对吧?
我想你能看出来,我是 Go 的新手,而且我还没有真正研究过接口…[编辑] 我可能应该去研究一下!
很多人觉得
interface{}是 Go 中的一个特殊类型,但实际上它和上面变量y的类型定义是同一个东西,只是interface{}在其{和}之间没有列出任何方法,所以它被明确地称为 “空接口”。
啊,是的,空接口,这个我确实记得读到过。那么基本上可以说,一个 interface{} 几乎可以是任何东西,有点像 C# 中的 Object,是吗?当然,在我这个特定的 GTK 树视图案例中,GTK 的开发者不想限制用户能在树视图中放入什么内容,所以他们要求:告诉我们你有多少列(int),以及你希望每列包含什么(interface{})。最后这个参数可以是任何东西,具有任何方法签名……?
既然你可以向树视图中添加图像、文本、进度条等等,我想你基本上无法对能放入其中的内容做任何限定。
附言:感谢你详尽且信息量丰富的回答……这对我来说真的是一个“啊哈”时刻 🙂
是的。我的观点是,大括号的存在是因为 []interface{} 表示“一个实现了空接口的元素的切片”。类似地,[]interface{ String() string } 表示“一个拥有返回 string 的 String() 方法的元素的切片”。
你可以使用类型字面量(例如 interface{}、interface{ String() string }、struct{ S string, I int} 等),也可以定义你自己的类型,使其拥有一个名称:
type Anything interface {
// No methods needed to implement this interface.
// It is the empty interface.
}
type Stringer interface {
String() string
}
type MyStruct struct {
S string
I int
}
然后你就可以直接使用这些名称:
values := []Anything{
thumbnail,
video.SubscriptionName,
video.Added.Format(constDateLayout),
video.Title,
progress,
backgroundColor,
video.ID,
duration,
progressText,
foregroundColor,
}
在Go语言中,[]interface{}{...} 的语法是正确的,它创建了一个 interface{} 类型的切片(即空接口切片)。这里有两层花括号的原因如下:
- 第一层花括号
[]interface{}:这是类型声明,表示一个空接口切片。 - 第二层花括号
{...}:这是复合字面量(composite literal),用于初始化切片中的元素。
相比之下,[]int{...} 只有一层花括号,因为它将类型声明和初始化合并了。实际上,[]interface{}{...} 也可以写成 []interface{}{...}(中间没有空格),但为了清晰,通常会在类型和初始化值之间加空格。
示例代码:
package main
import "fmt"
func main() {
// 示例1: int切片初始化
intSlice := []int{1, 2, 3}
fmt.Println(intSlice) // 输出: [1 2 3]
// 示例2: interface{}切片初始化
ifaceSlice := []interface{}{"字符串", 42, true, 3.14}
fmt.Println(ifaceSlice) // 输出: [字符串 42 true 3.14]
// 示例3: 多行初始化(更清晰)
treeViewData := []interface{}{
thumbnail,
video.SubscriptionName,
video.Added.Format(constDateLayout),
video.Title,
progress,
backgroundColor,
video.ID,
duration,
progressText,
foregroundColor,
}
// 使用treeViewData...
}
在你的GTK代码中:
// 两种写法等价:
// 1. 紧凑写法
[]interface{}{value1, value2, value3}
// 2. 标准写法
[]interface{}{
value1,
value2,
value3,
}
关键点:
interface{}是Go中的空接口类型,可以容纳任何类型的值- 当类型本身包含花括号(如
[]interface{})时,初始化需要额外的花括号 - 这与
map[string]int{"a": 1}的语法类似,类型声明中已经包含花括号
这种语法设计确保了类型声明的完整性,同时允许清晰的复合字面量初始化。

