簡體   English   中英

在Go中將函數轉換為另一種類型(函數轉換)

[英]Convert function to another type (function casting) in Go

我最近了解到,在net/http程序包中,有一種用法使我最困惑。 這是函數類型轉換。 就像這樣:

(function a) ->convert to-> (type t)
(type t) ->implentments-> (interface i)

因此,如果有一個將接口i作為參數的函數,它將調用函數a,這就是net/http實現它的方式。

但是當我編寫自己的代碼時,我對這種模式有很多誤解。 我的代碼是這樣的:

package main

import (
    "fmt"
)

type eat interface {
    eat()
}
type aaa func()

func (op *aaa) eat() {//pointer receiver not right
    fmt.Println("dog eat feels good")
}

///////////////////////////////////////////////
func dog() {
    fmt.Println("I'm a dog")
}
///////////////////////////////////////////////

func feelsGood(a eat) {
    a.eat()
}

func main() {
    b := aaa(dog)
    feelsGood(b)
}

//error:aaa does not implement eat (eat method has pointer receiver)

類型aaa具有方法eat,相同的函數名和參數簽名,符合接口eat的規則,但是為什么會出現該錯誤? 接收者重要嗎?

另一個問題是僅包含函數和類型,不包括接口,代碼如下所示:

package main

import (
    "fmt"
)

type aaa func()

func (op *aaa) eat() {
    op()
}

///////////////////////////////////////////////
func dog() {
    fmt.Println("I'm a dog")
}
///////////////////////////////////////////////

func main() {
    obj:=aaa(dog)
    obj.eat()
}
//error:cannot call non-function op (type *aaa)

首先, op具有匿名函數,而與錯誤無關?

其次,在刪除星號后它可以正常工作,但是為什么呢? opaaa類型的實例,接收者是opop代表函數dog()嗎? http包以相同的方式使用f(w,r) ,但有點難以理解。 op是類型,實例還是匿名函數?

似乎我對函數轉換的理解不正確,但是我也檢查了Google上的許多帖子,沒有一個可以教我如何思考和正確使用它。謝謝!

問題1:

在Go中,對於類型T(例如您的aaa), T*T具有不同的方法集。

因此,類型T的值只能訪問方法:

func(t T)Foo() { ... }

雖然* T類型的值可以訪問這兩種方法:

func(t T)Foo() { ... }
func(t *T)Bar() { ... }

就您而言,您有兩個選擇。 您可以聲明aaaeat方法,而不是od *aaa

func (op aaa) eat() {
    op()
}

或者,您將指針傳遞給bfeelsGood

feelsGood(&b)

問題2:

是的,這個問題與第一個有關。 但是在這種情況下,您可以訪問該方法,因為obj.eat()(&obj).eat()

您的問題在於,無法在函數指針(op * aaa)上調用函數。 您的選擇是為aaa而非*aaa創建方法:

func (op aaa) eat() {
    op()
}

或在值而不是指針上調用op函數:

func (op *aaa) eat() {
    (*op)()
}

對於您問題的第一部分:請參閱http://golang.org/doc/faq#different_method_sets ,該示例比我能更好地舉例說明了一切。 您甚至可以在stackoverflow和golang-nuts郵件列表中搜索該問題,因為它經常出現。

第二個是相同的恕我直言: aaa沒有eat方法(只有*aaa擁有)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM