2017-03-07 118 views
0

此代码工作正常:呼叫结构方法

feedService := postgres.FeedService{} 
feeds, err := feedService.GetAllRssFeeds() 

但这个代码给我错误:

feeds, err = postgres.FeedService{}.GetAllRssFeeds() 

controllers\feed_controller.go:35: cannot call pointer method on postgres.FeedService literal controllers\feed_controller.go:35: cannot take the address of postgres.FeedService literal

为什么这两段代码不等于?

这里是一个结构声明:

type FeedService struct { 

} 

func (s *FeedService) GetAllRssFeeds() ([]*quzx.RssFeed, error) { 
+0

“为什么这两段代码不相等?”因为语言规范是这样说的。错误信息是非常明显的,或? – Volker

回答

4

FeedService.GetAllRssFeeds()方法指针接收器,所以需要一个指针FeedService调用此方法。

在第一个示例中,您使用short variable declarationFeedService结构值存储在局部变量中。局部变量是addressable,所以当您在此之后编写feedService.GetAllRssFeeds()时,编译器将自动获取feedService的地址并将其用作接收器值。这是一个简写:

feeds, err := (&feedService).GetAllRssFeeds() 

这是Spec: Calls:

If x is addressable and &x 's method set contains m , x.m() is shorthand for (&x).m() .

在第二个例子中,你没有创建一个局部变量,你只使用结构composite literal,但它本身并不(自动)可寻址,因此编译器无法获得指向FeedService值的指针作为接收方,因此无法调用该方法。

注意,它被允许采取的复合字面明确地址,所以下面也可以工作:

feeds, err := (&postgres.FeedService{}).GetAllRssFeeds() 

这是Spec: Composite literals:

Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.

请参阅相关的问题:

What is the method set of `sync.WaitGroup`?

Calling a method with a pointer receiver by an object instead of a pointer to it?