Работа с gen

7 minute read

Gen - сборная солянка идей из C#’s Linq, JavaScript’s Array методов и библиотеки underscore. И все это оформлено в некоторое подобие дженериков.

На самом деле, это генератор кода, который может ускорить работу с множествами.

Например, если у вас есть некоторый тип SomeType, то теперь не нужно таскать из проекта в проект куски кода для работы с срезами, типа []*SomeType. Можно одной командой сгенерировать целую пачку методов, таких как Count, Where и т.д.

Использование

Ставится как большинство пакетов:

$ go get github.com/clipperhouse/gen

Чтобы начать работу, нужно определить новый тип, и приписать магический комментарий.

// +gen
type SomeType struct {
    Id string
}

Теперь запускаем gen в папке с файлом, в котором описан наш тип и получаем еще один файл, в котором будут описаны все методы для этого типа.

У меня новый тип определен в файле это main.go. Соответственно, рядом появился файл sometype_gen.go

Генерацией методов можно управлять через тот же магический комментарий. Например, можно генерировать методы для указателя на структуру:

// +gen *
type SomeType struct {
    //...
}

Сгенерирует методы для:

type SomeType []*SomeType

Можно указать, какие именно методы должны генерироваться:

// +gen * methods:"Any,Where,Count"
type SomeType struct {
    //...
}

Или наоборот, не должны генерироваться:

// -gen * methods:"Any,Where,Count"
type SomeType struct {
    //...
}

Этот магический комментарий работает аналогично тегам в структурах, поэтому стоит придерживаться схожего синтаксиса.

Кроме тега methods можно указать тег projections, который позволит сгенерировать дополнительные полезные методы для определенных типов в структуре.

// -gen * projections:"int"
type SomeType struct {
    Id int
}

И последний тег - containers. Поможет сгенерировать дополнительные структуры данных, которые можно юзать для своих нужд.

// +gen containers:"Set,List,Ring"
type SomeType struct {
    //...
}

Непонятности

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

Проще говоря, если ваш проект будет иметь такую структуру:

gentest/
    |- bin/
    |- pkg/
    |- src/
    |   |-4gophers.com/
    |        |-/somepackage/
    |            |-file.go
    |            |-somefile.go
    |- main.go
    |- activate.sh
    |- Gomfile

И путь к gentest будет дополнительно добавлен в GOPATH

$GOPATH=/home/user/go1.2/global:/home/user/Projects/gentest/vendor:/home/kovardin/Projects/gentest

То при использовании gen в корне вылезет такая ошибка:

error: main.go:5:5: could not import 4gophers.com/somepackage (can't find import: 4gophers.com/
somepackage)
error: failed to evaluate type SomeType (-: undeclared name: SomeType)
operation canceled
use the -f flag if you wish to force generation (i.e., ignore errors)

И даже gen -f не поможет.

Свои шаблоны

Их нет. А я хочу)