Подтвердить что ты не робот

Можем ли мы иметь указатели на функции в Go?

Я изучал указатели в Go. И удалось написать что-то вроде:

func hello(){

       fmt.Println("Hello World")
}

func main(){

       pfunc := hello     //pfunc is a pointer to the function "hello"
       pfunc()            //calling pfunc prints "Hello World" similar to hello function
}

Есть ли способ объявить указатель функции, не определяя его, как сделано выше? Можем ли мы написать что-то похожее на C?

например void (*pfunc)(void);

4b9b3361

Ответ 1

Он работает, если вы используете подпись. Нет указателя.

type HelloFunc func(string)

func SayHello(to string) {
    fmt.Printf("Hello, %s!\n", to)
}

func main() {
    var hf HelloFunc

    hf = SayHello

    hf("world")
}

В качестве альтернативы вы можете напрямую использовать подпись функции, не объявляя новый тип.

Ответ 2

Go не имеет такой же синтаксис для указателей на функции, как C и C++. Это очень хорошее объяснение в блоге Go. Понятно, что авторы Go считали синтаксис C для указателей на функции слишком похожим на обычные указатели, поэтому вкратце они решили сделать указатели на функции явными; то есть более читабельным.

Вот пример, который я написал. Обратите внимание, как параметр fp определен в calculate() и в другом примере ниже, который показывает вам, как вы можете сделать указатель на функцию в типе и использовать его в функции (функция вычисления с комментариями).

package main

import "fmt"

type ArithOp func(int, int)int

func main() {
    calculate(Plus)
    calculate(Minus)
    calculate(Multiply)
}

func calculate(fp func(int, int)int) {
    ans := fp(3,2)
    fmt.Printf("\n%v\n", ans) 
}

// This is the same function but uses the type/fp defined above
// 
// func calculate (fp ArithOp) {
//     ans := fp(3,2)
//     fmt.Printf("\n%v\n", ans) 
// }

func Plus(a, b int) int {
    return a + b
}

func Minus(a, b int) int {
    return a - b
}

func Multiply(a,b int) int {
    return a * b
}

Параметр fp определяется как функция, которая принимает два целых числа и возвращает одно целое число. Это примерно то же самое, что упоминалось Mue, но показывает другой пример использования.

Ответ 3

Вы можете сделать это следующим образом:

package main

import "fmt"

func hello(){

       fmt.Println("Hello World")
}

func main(){
       var pfunc func()
       pfunc = hello     //pfunc is a pointer to the function "hello"
       pfunc()            
}

Если ваша функция имеет аргументы и, например, возвращаемое значение будет выглядеть так:

func hello(name string) int{

       fmt.Println("Hello %s", name)
       return 0
}

и переменная будет выглядеть так:

  var pfunc func(string)int

Ответ 4

Функция также является типом в Go. Таким образом, вы можете создать переменную сигнатуры типа func. Следующее будет работать;

var pfunc func(string)

Эта переменная может указывать на любую функцию, которая принимает строку в качестве аргумента и ничего не возвращает. Следующий фрагмент кода работает хорошо.

package main

import "fmt"

func SayHello(to string) {
    fmt.Printf("Hello, %s!\n", to)
}

func main() {
    var pfunc func(string)

    pfunc = SayHello

    pfunc("world")
}

Ответ 5

Другой способ подойти к этому - определить интерфейс

type command interface {
      DoLoop()
}

реализовать структуру, которая реализует ее

type Delete struct {
      instance string
}

func (dev Delete) DoLoop() {
      fmt.Println("input: delete ")
}

Создайте карту, которая содержит структуру

 mainFuncTable = make(map[string]command)
 mainFuncTable["delete"] = Delete{"new"}

вызов функции

func route(command string) {
      cmd := mainFuncTable[command]
      cmd.DoLoop()
}

Это немного косвенно, но это работает