Присвоить метод структуры типу функции

Как можно присвоить метод типу функции? Есть ли какая-то магия, позволяющая Go отслеживать получателя? Если да, может ли кто-нибудь указать мне, где это задокументировано? Я посмотрел, но отсутствие времени на Go, вероятно, означает, что я использую неправильную терминологию.

Следующий код демонстрирует функциональность, которую я не понимаю.

// My code
struct MyController {
  ...
}
func (mc MyController) GetMyStuff(w http.ResponseWriter, r *http.Request) {
 ....
}

// My HTTP Server class
mc := MyController{..}

http.HandleFunc("/stuff", mc.GetMyStuff)
http.ListenAndServe(":3000", nil)

Вначале я писал методы MyController для возврата http.HandlerFunc, а затем фиксировал ссылку на MyController в реализации. Однако сейчас это кажется излишним и ненужным. Go pro — что более идиоматично?

func (mc MyController) GetMyStuff() http.HandlerFunc {
   return func(w http.ResponseWriter, r *http.Request) {
      // Use mc.{receiver/type} to capture mc reference
   }
}

Почему бы не реализовать pkg.go.dev/net/http#Handler непосредственно для MyController?

Markus W Mahlberg 06.07.2024 18:57

Мне это даже в голову не пришло. Большинство моих классов контроллеров имеют набор обработчиков. Однако этот подход заставил бы меня написать меньшие классы контроллера/маршрутизатора. Это, вероятно, было бы чище и проще в обслуживании для сплоченности классов. Спасибо

Freddy 07.07.2024 05:38
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эти разделы спецификации описывают это:

https://go.dev/ref/spec#Method_expressions

https://go.dev/ref/spec#Method_values ​​

Вкратце: если вы создаете функциональную переменную из метода, эта функциональная переменная захватывает получателя метода. То есть:

type X struct{
  Value int
}

func (x X) F() {
  return x.Value
}

Затем вы можете сделать:

a:=X{Value:1}
x1:=a.F  // x1 has a reference to a
b:=X{Value:2}
x2:=b.F  // x2 has a reference to b
fmt.Println(x1(),x2()) // Prints 1 2

Другие вопросы по теме