英文:
Structs in GoLang
问题
我刚开始学习Go语言,并且正在查看他们的一个教程(https://golang.org/doc/code.html)。
在他们的一个示例中,他们将一个变量设置为一个结构体,但是我对于他们如何在下面的for循环中访问结构体的元素感到非常困惑。有没有人可以解释一下?非常感谢!
代码:
package stringutil
import "testing"
func TestReverse(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}
英文:
I am just starting with GoLang, and I am looking at one of their tutorials (https://golang.org/doc/code.html).
In one of their examples, they set a variable to a struct, but I am so confused as to how they are accessing elements of the struct in the for loop below? Any chance someone can clarify? Thanks alot!
Code:
package stringutil
import "testing"
func TestReverse(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}
答案1
得分: 8
以下是带有一些注释的代码,以帮助澄清每个语句在其中的作用。
import "testing"
func TestReverse(t *testing.T) {
cases := []struct { // 声明匿名类型
in, want string // 该类型上的字段 in 和 want,都是字符串类型
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
} // 复合字面初始化
// 注意在对 cases 进行赋值时使用了 :=,这个操作符将声明和赋值合并为一条语句
for _, c := range cases { // 遍历 cases,忽略索引 - 下划线表示丢弃该返回值
got := Reverse(c.in) // c 是当前实例,使用熟悉的点符号访问 in 字段
if got != c.want { // 再次使用访问操作符访问 c,即当前实例
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) // 更多的访问操作
}
}
}
希望这有所帮助。如果需要,我可以尝试用口语化的语言进行更详细的总结,或者如果某些语句仍然不清楚,我可以添加更多细节。另外,如果你对 range 不熟悉的话,它会在集合上进行迭代,并返回 k, v
,其中 k
是索引或键,v
是值。
编辑:关于 cases
的声明/初始化的详细信息
cases := []struct {
in, want string
}
在第一对花括号内的部分是一个结构体的定义。这是一个匿名类型,正常的声明看起来像这样:
type case struct {
in string
want string
}
如果你有类似这样的声明,那么在该包的作用域中会有一个名为 case
的类型(如果你想将其公开,那么需要将其命名为 Case
)。而在这里,cases
结构体是匿名的。它与普通类型的工作方式相同,但作为开发者,你无法引用该类型,因此只能在此处实际使用初始化的集合。在内部,该类型与任何其他具有两个未导出字符串字段的结构体相同。字段名为 in
和 want
。请注意,在赋值 cases := []struct
中,[]
在 struct
之前,这意味着你正在声明一个该匿名类型的切片。
接下来的一小部分被称为静态初始化。这是一种用于初始化类型的集合的语法。每个嵌套的部分,如 { "","" }
,都是一个匿名结构体的声明和初始化,再次由花括号表示。在这种情况下,你将两个空字符串分别赋给 in
和 want
(如果不使用名称,则顺序与定义中的顺序相同)。外部的花括号是用于切片的。如果你的切片是 int 或 string 类型,那么你只需在那里直接写入值,而不需要额外的嵌套层级,例如 myInts := []int{5,6,7}
。
{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
英文:
Below is the code with some comments to help clarify each statements role in this.
import "testing"
func TestReverse(t *testing.T) {
cases := []struct { // declaration of anonymous type
in, want string // fields on that type called in and want, both strings
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
} // composite literal initilization
// note the use of := in assigning to cases, that op combines declaration and assignment into one statement
for _, c := range cases { // range over cases, ignoring the index - the underscore means to discard that return value
got := Reverse(c.in) // c is the current instance, access in with the familiar dot notation
if got != c.want { // again, access operator on c, the current instance
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want) // more access
}
}
}
Let me know if that helps. I can try giving more of a summary in spoken language or add more details if some of the statements don't make sense still. Also, fyi if you're not familiar range 'ranges' over a collection, returning k, v
where k
is the index or key and v
the value.
EDIT: details on the declaration/initilization of cases
cases := []struct {
in, want string
}
This bit inside the first pair of curly braces is the definition of a struct. This is an anonymous type, a normal declaration would look like this;
type case struct {
in string
want string
}
If you had something like this then there would be a type called case
in the scope of this package (not exported, if you wanted to make it 'public' so it would need to be type Case
instead). Instead the examples struct is anonymous. It works the same as normal type, however as a developer, you will have no way to reference that type so you can only practically work with the collection initialized here. Internally this type is the same as any other struct with 2 unexported strings for fields. The fields are named in
and want
. Notice that in the assignment here cases := []struct
you have []
before struct
this means you're declaring a slice of this anonymous type.
This next little bit, is called static initialization. This is a syntax for initializing collections as types. Each of these nested bits like {"", ""}
is the declaration and initilization of one of these anonymous structs, denoted again by the curly braces. In this case you're assigning two empty strings to in
and want
respectively (if you don't use names, the order is the same as in the definition). The outer pair of braces is for the slice. If your slice were of say int's or string's, then you would just have the values right there without the extra level of nesting like myInts := []int{5,6,7}
.
{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
答案2
得分: 1
前往了解什么是结构体。
你在结构体中声明变量,然后可以从函数中使用它。
示例:
package main
import (
"fmt"
)
func main() {
Get()
}
func Get() {
out := new(Var)
out.name = "james"
fmt.Println(out.name)
}
type Var struct {
name string
}
英文:
Go root of what is a struct.
you declare your variables in it so then
you can use it from a function.
Example:
package main
import (
"fmt"
)
func main() {
Get()
}
func Get(){
out := new(Var)
out.name = "james"
fmt.Println(out.name)
}
type Var struct {
name string
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论