Go における関数ポインタの落とし穴とベスト プラクティス: 落とし穴: 使用できない関数を指すポインタ ベスト プラクティス: ローカル変数またはクロージャを使用して関数の値をキャプチャします。落とし穴: ポインタが指す関数を変更する ベスト プラクティス: 関数ポインタを変更できないようにし、別のクロージャで新しい関数を作成します。実際のケース: コールバック関数 たとえば、関数ポインターを使用して、ログ メッセージと重大度レベルをコールバック関数のパラメーターとして受け取るログ関数を作成します。
Go における関数ポインターの罠とベスト プラクティス
Go では、関数ポインターは、関数を次のように受け取る関数です。値 配信のための強力なメカニズム。ただし、関数ポインターを使用するときに注意すべきいくつかの罠があります。
罠 1: 関数ポインターが使用できない関数を指している
関数ポインターが使用できない関数を指している場合使用できなくなった関数を使用すると、ダングリング ポインター エラーが発生します:
func newFunc() { // ... } func main() { newFuncPtr := newFunc // 将函数 newFunc 赋值给指针 newFuncPtr newFunc = nil // 将 newFunc 设为 nil,使其不可用 newFuncPtr() // 这会触发悬空指针错误 }
ベスト プラクティス: ローカル変数またはクロージャーを使用して関数の値をキャプチャします
ダングリング ポインターを回避するには、関数の値をローカルにキャプチャする 変数またはクロージャ内:
func main() { newFunc := newFunc newFunc() // 仍然有效,因为它捕获了 newFunc 的副本 }
トラップ 2: ポインターが指す関数を変更する
関数が指す関数を変更するポインタは予期しない結果を引き起こす可能性があります:
type API interface { Call() } func makeAPI() API { return func() { fmt.Println("Hello") } } func main() { apiPtr := makeAPI() apiPtr = func() { fmt.Println("Goodbye") } apiPtr.Call() // 输出 "Goodbye" }
ベスト プラクティス: 関数ポインタを変更できないようにする
関数の動作を変更する必要がある場合は、別のクロージャで新しい関数を作成します。
func main() { api := makeAPI() api = func(a API) API { return func() { fmt.Println("Goodbye") a.Call() } }(api) api.Call() // 输出 "Hello", 然后是 "Goodbye" }
実用的なケース: コールバック関数
コールバック関数は、イベントの発生時に呼び出し元に通知するために使用される関数ポインターの一般的な例です。
たとえば、関数ポインタを使用して、ログ メッセージと重大度レベルをコールバック関数の引数として受け取るログ関数を構築できます。
import "fmt" import "log" type Severity string const ( Info Severity = "INFO" Warning Severity = "WARNING" Error Severity = "ERROR" ) func Log(severity Severity, message string) { log.Println(fmt.Sprintf("%s: %s", severity, message)) } // 获取 severity 为 Info 的日志函数 func InfoLogger() func(string) { return func(message string) { Log(Info, message) } }
コールバック関数を使用して、次のことができます。ログ関数に送信されたログ メッセージを渡します:
func main() { infoLogger := InfoLogger() infoLogger("Hello, world!") // 输出:INFO: Hello, world! }
以上がGolang 関数ポインターの落とし穴とベスト プラクティスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。