Анонимные функции. Замыкания

В этой главе мы сделаем первую 100% работающую версию нашего приложения!

Напомню, наше приложение должно регистрировать обращения к счетику и выдавать статистику о текущей посещаемости (пока ограничимся счетчиком посетителей).

Напишем структуру у которой будут две функции:

  • RegisterHit() - будет регистрировать событие
  • TotalHits() - будет возвращать количество зарегистрированных событий
type Datastore struct {
    hitCounter int
}

func (ds *Datastore) RegisterHit() {
    ds.hitCounter++
}

func (ds *Datastore) TotalHits() int {
    return ds.hitCounter
}

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

Создайте пакет app/datastore и добавьте туда данную струкуру.

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

Изменим файл handlers/stat.go следующим образом:

package handlers

import (
    "fmt"
    "github.com/labstack/echo"
    "net/http"
    ds "app/datastore"
)

func Stat(ds *ds.Datastore) echo.HandlerFunc {
    return func(c echo.Context) error {
        return c.String(http.StatusOK, fmt.Sprintf(`{ "total": %d }`, ds.TotalHits()))
    }
}

Обратите внимание на импорт пакета ds "app/datastore". В PHP мы бы написали use App\Datastore as ds;. Теперь мы можем использовать короткую версию ds
для обращению к данным внутри пакета, вместо полной версии datastore

Далее, мы изменили функцию Stat таким образом, чтобы она возвращала обработчик http запроса. Для формирования JSON мы воспользовались встроенным пактом fmt который отвечает за форматирование ввода и вывода.

Короче, если бы мы писали на PHP, то код мог бы выглядеть так:

function Stat($ds ds\Datastore) {
    return function($c) use ($ds) {
        return $c->String(200, sprintf('{ "total": %d }', $ds->TotalHits()));
    }
}

Измените файл handlers/counter.go по аналогии с handlers/stat.go самостоятельно.

Осталось создать экземпляр нашего datastore в main.go и передать его в обработчики.

func main() {
    ds := datastore.Datastore{}

    e := echo.New()
    e.GET("/stat.js", handlers.Stat(&ds))
    e.GET("/counter.js", handlers.Counter(&ds))
    e.Start(":8080")
}

Запустите приложение и откройте http://localhost:8080/counter.js, а затем http://localhost:8080/stat.js. Если вы все сделали правильно, то увидите

{ "total": 1 }

Все, первая версия нашего приложения готова! Однако не надо радоваться, проблем в нем больше чем достаточно. Более того, оно скорее всего упадет при высокой нагрузке. Какие проблемы есть и что можно улучшить расскажу далее.

Код находится в src/anonymous_functions.

results matching ""

    No results matching ""