我如何在Go中表达一个类型是"(字符串或其他此类列表)的列表"?基本上是好的' "树表示为无限嵌套的列表列表和某些值(本例中的字符串)"
我正在寻找一个S表达式的最简单的表示形式(它本身就是最简单的AST),在Python中看起来像这样:
glVertex3f(20.0, 20.0, 0.0);
glVertex3f(80.0, 20.0, 0.0);
glVertex3f(80.0, 80.0, 0.0);
glVertex3f(20.0, 80.0, 0.0);
这些表达式在Go中有哪些类型?显然sexp1 = ["+", "x", "y", ["*", "10", "myVal"]]
sexp2 = ["foo" "bar" "baz"]
sexp3 = [ [ [["gooo"], "moo"] ], "too", ["yoo", "2"] ]
不起作用,因为这不起作用:
[][]string
(编译错误:1。func makeSexp(parserName string, values ...[][]string) [][]string {
return append([]string{parserName}, values...)
}
,2。cannot use values (type [][][]string) as type []string in append
。)
...虽然完全无类型的版本有效(但我不想完全放弃类型安全!):
cannot use append([]string literal, values...) (type []string) as type [][]string in return argument
答案 0 :(得分:5)
不幸的是,Go不支持代数数据类型,所以最好将其设置为类型安全的是创建一个未导出的接口,并进行两次实现:
type sExp interface {
sExp()
}
type s string
func (s) sExp() {}
type l []sExp
func (l) sExp() {}
// ...
var sexp1 sExp = l{s("+"), s("1"), s("2"), l{s("*"), s("10"), s("myVal")}}
这基本上是Protobuf编译器处理的例子。 oneof
个案例。这仍然需要很多类型的开关或类型断言才能使用,但至少你可以确定你的模块之外的任何东西都不能修补它。