2017-03-07 111 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?