DevGang
Авторизоваться

Как использовать дженерики Golang со структурами 

Начиная с версии Go 1.18 у нас наконец появилась сила дженериков. На этой неделе, когда я просматривал исходный код Golang, я нашел пример того, как создавать структуры с помощью дженериков.

В этом посте я покажу вам, как это сделать.

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

package blog

type Category struct {
    ID int32
    Name string
    Slug string
}

type Post struct {
    ID int32
    Categories []Category
    Title string
    Description
    Slug string
}

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

Имея в виду эти спецификации, давайте создадим новый пакет с именем cache.

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

package cache

type cacheable interface {
    blog.Category | blog.Post
}

Хорошо! Теперь мы можем создать нашу частную и общую структуру для хранения данных.

type cache[T cacheable] struct {
    data[string]T
}

Чтобы манипулировать данными, мы реализуем два метода: Set и Get.

func (c *cache[T]) Set(key string, value T) {
    c.data[key] = value
}

func (c *cache[T]) Get(key string) (v T) {
    if v, ok := c.data[key]; ok {
        return v
    }

    return
}

Теперь давайте добавим общую функцию для создания и возврата указателя на новый кеш.

func New[T cacheable]() {
    c := cache[T]{}
    c.data = make(map[string]T)

    return &c
}

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

func main() {
    // create a new category
    category := blog.Category{
        ID: 1,
        Name: "Go Generics",
        Slug: "go-generics",
    }
    // create cache for blog.Category struct
    cc := cache.New[blog.Category]()
    // add category to cache
    cc.Set(category.Slug, category)

    // create a new post
    post := blog.Post{
        ID: 1,
        Categories: []blog.Category{
            {ID: 1, Name: "Go Generics", Slug: "go-generics"},
        },
        Title: "Generics in Golang structs",
        Text: "Here go's the text",
        Slug: "generics-in-golang-structs",
    }
    // create cache for blog.Post struct
    cp := cache.New[blog.Post]()
    // add post to cache
    cp.Set(post.Slug, post)
}
#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться