Go语言中的结构体(Structs)

huangapple go评论83阅读模式
英文:

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 结构体是匿名的。它与普通类型的工作方式相同,但作为开发者,你无法引用该类型,因此只能在此处实际使用初始化的集合。在内部,该类型与任何其他具有两个未导出字符串字段的结构体相同。字段名为 inwant。请注意,在赋值 cases := []struct 中,[]struct 之前,这意味着你正在声明一个该匿名类型的切片。

接下来的一小部分被称为静态初始化。这是一种用于初始化类型的集合的语法。每个嵌套的部分,如 { "","" },都是一个匿名结构体的声明和初始化,再次由花括号表示。在这种情况下,你将两个空字符串分别赋给 inwant(如果不使用名称,则顺序与定义中的顺序相同)。外部的花括号是用于切片的。如果你的切片是 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
}

huangapple
  • 本文由 发表于 2015年12月19日 03:29:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/34362649.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定