在golang中获取结构体中的操作。

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

Get operation in a structure in golang

问题

以下是一个简单的程序。但我不明白的是,Get操作是如何工作的?我没有定义任何Get方法,但form.Get却能正常工作。为什么?

诚挚地,
Sudarsan.D

package main

import (
	"fmt"
	"net/url"
)

type errors map[string]string;

type Form struct {
	url.Values;
	Errors errors;
}

func New(data url.Values) (*Form) {
	return &Form {
		data,
		errors(map[string]string{}),
	};
}


func main() {
	k1 := url.Values{};
	k1.Set("arvind","superstar");
	k1.Set("title","Arvind");
	form := New(k1);
	fmt.Println("The title is", form.Get("arvind"));
}
英文:

Below is a simple program. But what I don't understand is that how is the Get operation working? I have not defined any Get Method, but form.Get is working. How?

Sincerely,
Sudarsan.D

package main

import (
       "fmt"
	   "net/url"
)

type errors map[string]string;

type Form struct {
	url.Values;
	Errors errors;
}

func  New (data url.Values) (*Form) {
    return &Form {
	    data,
	    errors(map[string]string{}),
    };
}


func main () {
   k1 := url.Values{};
   k1.Set("arvind","superstar");
   k1.Set("title","Arvind");
   form := New(k1);
   fmt.Println("The title is", form.Get("arvind"));
}

答案1

得分: 1

因为在Form结构体中,你没有为url.Values字段显式提供名称,所以该字段被称为嵌入字段。嵌入字段的名称会自动设置为类型的非限定名称,即在这种情况下,url.Values字段的名称变为Values。此外,嵌入字段类型的方法(如果有)和字段(如果是带有字段的结构体)被称为提升到嵌入结构体。通过嵌入结构体可以直接访问提升的方法或字段,而无需指定嵌入字段的名称。例如,你可以使用form.Get("arving")而不是form.Values.Get("arvind")

请注意,两个表达式form.Values.Get("arvind")form.Get("arving")在语义上是等价的。在两种情况下,你都是在调用form.Values字段上的Get方法,即使在第二个表达式中省略了字段的名称。

结构体类型的语言规范中可以得知:

结构体是一系列具有名称和类型的命名元素,称为字段。字段的名称可以显式指定(IdentifierList)或隐式指定(EmbeddedField)。

...

**具有类型但没有显式字段名称的字段称为嵌入字段。**嵌入字段必须指定为类型名称T或非接口类型名称*T的指针,并且T本身不能是指针类型。非限定类型名称充当字段名称。

...

结构体x中的嵌入字段f的字段或方法f称为提升,如果x.f是合法的选择器,表示该字段或方法f

...

给定结构体类型S和定义的类型T,提升的方法包括在结构体的方法集中,如下所示:

  • 如果S包含嵌入字段T,则S*S的方法集都包括具有接收器T的提升方法。*S的方法集还包括具有接收器*T的提升方法。
  • 如果S包含嵌入字段*T,则S*S的方法集都包括具有接收器T*T的提升方法。
英文:

Because in the Form struct you did not provide a name explicitly for the url.Values field, that field is said to be embedded. An embedded field's name is automatically set to the type's unqualified name, i.e. in this case the url.Values field's name becomes Values. Also, an embedded field type's methods (if it has any) and fields (if it is a struct with any) are said to be promoted to the embedding struct. A promoted method or field can be accessed directly through the embedding struct, without having to specify the embedded field's name. i.e. instead of form.Values.Get("arvind") you can do form.Get("arving").

Keep in mind that the two expressions form.Values.Get("arvind") and form.Get("arving") are semantically equivalent. In both cases you are calling the method Get on the form.Values field even though in the second expression the field's name is omitted.


From the language spec on Struct types:

> A struct is a sequence of named elements, called fields, each of which
> has a name and a type. Field names may be specified explicitly
> (IdentifierList) or implicitly (EmbeddedField)
.
>
> ...
>
> A field declared with a type but no explicit field name is called an
> embedded field.
An embedded field must be specified as a type name T
> or as a pointer to a non-interface type name *T, and T itself may not
> be a pointer type. The unqualified type name acts as the field name.
>
> ...
>
> A field or method f of an embedded field in a struct x is called
> promoted if x.f is a legal selector that denotes that field or method
> f.

>
> ...
>
> Given a struct type S and a defined type T, promoted methods are
> included in the method set of the struct as follows:
>
> - If S contains an embedded field T, the method sets of S and *S both
> include promoted methods with receiver T. The method set of *S also
> includes promoted methods with receiver *T.

> - If S contains an embedded
> field *T, the method sets of S and *S both include promoted methods
> with receiver T or *T.

huangapple
  • 本文由 发表于 2022年2月20日 21:56:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/71195107.html
匿名

发表评论

匿名网友

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

确定