英文:
Init array of structs in Go
问题
我是你的中文翻译助手,以下是翻译好的内容:
我在Go语言方面是个新手。这个问题让我很头疼。在Go语言中,如何初始化结构体数组?
type opt struct {
shortnm char
longnm, help string
needArg bool
}
const basename_opts []opt {
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "使用方式 a"
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "使用方式 b"
}
}
编译器报错说在[]opt
之后需要加上分号;
。
我应该在哪里放置大括号{
来初始化我的结构体数组?
英文:
I'm newbie in Go. This issue is driving me nuts. How do you init array of structs in Go?
type opt struct {
shortnm char
longnm, help string
needArg bool
}
const basename_opts []opt {
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a"}
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b"}
}
The compiler said it expecting ;
after []opt
.
Where should I put the braces {
to init my array of struct?
答案1
得分: 174
看起来你在这里使用的是(几乎)纯C代码。Go语言有一些不同之处。
首先,你不能将数组和切片初始化为const
。在Go语言中,const
一词的含义与C语言中不同。应该将列表定义为var
。
其次,作为一种风格规则,Go语言更喜欢使用basenameOpts
而不是basename_opts
。
Go语言中没有char
类型。你可能想要使用byte
(或者如果你打算允许Unicode码点,则使用rune
)。
在这种情况下,列表的声明必须具有赋值运算符。例如:var x = foo
。
Go语言的解析器要求列表声明中的每个元素都以逗号结尾,包括最后一个元素。这是因为Go语言会自动插入分号,所以需要更严格的语法才能正常工作。
例如:
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts = []opt {
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
另一种方法是使用类型声明列表,然后使用init
函数填充它。如果你打算在数据结构中使用函数返回的值,这种方法非常有用。init
函数在程序初始化时运行,并且保证在main
函数执行之前完成。你可以在一个包中拥有多个init
函数,甚至可以在同一个源文件中。
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts []opt
func init() {
basenameOpts = []opt{
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
}
由于你是Go语言的新手,我强烈建议你阅读语言规范。它非常简短且写得非常清晰,可以解决你遇到的许多小问题。
英文:
It looks like you are trying to use (almost) straight up C code here. Go has a few differences.
- First off, you can't initialize arrays and slices as
const
. The termconst
has a different meaning in Go, as it does in C. The list should be defined asvar
instead. - Secondly, as a style rule, Go prefers
basenameOpts
as opposed tobasename_opts
. - There is no
char
type in Go. You probably wantbyte
(orrune
if you intend to allow unicode codepoints). - The declaration of the list must have the assignment operator in this case. E.g.:
var x = foo
. - Go's parser requires that each element in a list declaration ends with a comma.
This includes the last element. The reason for this is because Go automatically inserts
semi-colons where needed. And this requires somewhat stricter syntax in order to work.
For example:
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts = []opt {
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
An alternative is to declare the list with its type and then use an init
function to fill it up. This is mostly useful if you intend to use values returned by functions in the data structure. init
functions are run when the program is being initialized and are guaranteed to finish before main
is executed. You can have multiple init
functions in a package, or even in the same source file.
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts []opt
func init() {
basenameOpts = []opt{
opt {
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
opt {
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
}
Since you are new to Go, I strongly recommend reading through the language specification. It is pretty short and very clearly written. It will clear a lot of these little idiosyncrasies up for you.
答案2
得分: 62
将此作为对@jimt优秀答案的补充:
一种常见的在初始化时定义所有内容的方法是使用匿名结构体:
var opts = []struct {
shortnm byte
longnm, help string
needArg bool
}{
{'a', "multiple", "使用方式 a", false},
{
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "使用方式 b",
},
}
这种方法通常也用于测试,以定义几个测试用例并循环执行它们。
英文:
Adding this just as an addition to @jimt's excellent answer:
one common way to define it all at initialization time is using an anonymous struct:
var opts = []struct {
shortnm byte
longnm, help string
needArg bool
}{
{'a', "multiple", "Usage for a", false},
{
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
This is commonly used for testing as well to define few test cases and loop through them.
答案3
得分: 5
你可以这样写:
在每个结构项或一组项后面加上逗号是很重要的。
earnings := []LineItemsType{
LineItemsType{
TypeName: "Earnings",
Totals: 0.0,
HasTotal: true,
items: []LineItems{
LineItems{
name: "Basic Pay",
amount: 100.0,
},
LineItems{
name: "Commuter Allowance",
amount: 100.0,
},
},
},
LineItemsType{
TypeName: "Earnings",
Totals: 0.0,
HasTotal: true,
items: []LineItems{
LineItems{
name: "Basic Pay",
amount: 100.0,
},
LineItems{
name: "Commuter Allowance",
amount: 100.0,
},
},
},
}
英文:
You can have it this way:
It is important to mind the commas after each struct item or set of items.
earnings := []LineItemsType{
LineItemsType{
TypeName: "Earnings",
Totals: 0.0,
HasTotal: true,
items: []LineItems{
LineItems{
name: "Basic Pay",
amount: 100.0,
},
LineItems{
name: "Commuter Allowance",
amount: 100.0,
},
},
},
LineItemsType{
TypeName: "Earnings",
Totals: 0.0,
HasTotal: true,
items: []LineItems{
LineItems{
name: "Basic Pay",
amount: 100.0,
},
LineItems{
name: "Commuter Allowance",
amount: 100.0,
},
},
},
}
答案4
得分: 2
我在搜索如何初始化结构体切片时遇到了这个答案。我自己只用Go语言工作了几个月,所以我不确定这个答案在问题提出时是否正确,或者只是一个新的更新,但是现在(不再)需要重新声明类型。请参考@jimt示例的重构版本:
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts = []opt {
{
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
{
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
英文:
I came across this answer while searching for how to initialize a slice of structs. I've been working with Go just a few months myself so I'm not sure if this was true at the time of the question or its just a new update but its not(no longer) necessary to restate the type. See a refactored version of @jimt's example
type opt struct {
shortnm byte
longnm, help string
needArg bool
}
var basenameOpts = []opt {
{
shortnm: 'a',
longnm: "multiple",
needArg: false,
help: "Usage for a",
},
{
shortnm: 'b',
longnm: "b-option",
needArg: false,
help: "Usage for b",
},
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论