由类型字面量定义的类型的结构字段上的方法

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

Method on a struct field of type defined by a type literal

问题

当解码JSON时,我总是明确地为每个对象编写一个结构体,以便我可以在父结构体中实现Stringer接口来处理单个对象,如下所示:

type Data struct {
	Records []Record
}

type Record struct {
	ID int
	Value string
}

func (r Record) String() string {
	return fmt.Sprintf("{ID:%d Value:%s}", r.ID, r.Value)
}

我最近了解到,可以使用匿名结构体进行嵌套。这种方法更简洁,用于定义要解码的数据的结构:

type Data struct {
	Records []struct {
		ID int
		Value string
	}
}

但是,是否可以为结构体的成员定义一个方法,特别是一个匿名结构体的成员?就像第一个代码块中的Stringer接口实现一样。

英文:

When decoding JSON I've always explicitly written a struct for each object so that I could implement the Stringer interface for individual objects in a parent struct like so:

type Data struct {
	Records []Record
}

type Record struct {
	ID int
	Value string
}

func (r Record) String() string {
	return fmt.Sprintf("{ID:%d Value:%s}", r.ID, r.Value)
}

I recently learned that it is possible to do nesting with anonymous structs. This method is much more concise for defining the structure of the data to be decoded:

type Data struct {
	Records []struct {
		ID int
		Value string
	}
}

But, is it possible to define a method on a member of a struct, particularly a member which is an anonymous struct? Like the Stringer interface implementation in the first code block.

答案1

得分: 6

不,方法只能附加到在同一个包中定义的命名类型。从规范中可以看到:

> 方法是带有接收器的函数。方法声明将一个标识符(方法名)绑定到一个方法上。它还将该方法与接收器的基本类型关联起来。

MethodDecl   = "func" Receiver MethodName Signature [ Body ] .
Receiver     = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
BaseTypeName = identifier .

> 接收器类型必须是T或*T的形式,其中T是类型名称。T所表示的类型称为接收器基本类型;它不能是指针或接口类型,并且必须在与方法相同的包中声明。该方法被称为绑定到基本类型,方法名仅在该类型的选择器中可见。

在第二个OP示例中,Records字段的类型是使用类型字面量定义的,即不满足上述的“类型名称”条件。

英文:

No, methods can be attached only to named types defined in the same package. From the specs:

> A method is a function with a receiver. A method declaration binds an identifier, the method name, to a method. It also associates the method with the receiver's base type.

MethodDecl   = "func" Receiver MethodName Signature [ Body ] .
Receiver     = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
BaseTypeName = identifier .

> The receiver type must be of the form T or *T where T is a type name. The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method. The method is said to be bound to the base type and the method name is visible only within selectors for that type.

The type of the Records field in the second OP example is defined using a type literal, ie. the 'type name' condition above is not met.

huangapple
  • 本文由 发表于 2013年1月1日 21:29:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/14110881.html
匿名

发表评论

匿名网友

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

确定