golang通过定义接口自动生成类型转换器插件库goverter的使用

Golang通过定义接口自动生成类型转换器插件库goverter的使用

概述

goverter是一个用于创建类型安全转换器的工具。你只需要创建一个接口并执行goverter命令即可。该项目是作为不使用反射的jinzhu/copier替代方案而设计的。

goverter logo

主要特性

  • 快速执行:运行时不需要使用反射
  • 自动转换内置类型:切片、映射、命名类型、原始类型、指针、具有相同字段的结构体
  • 枚举支持
  • 默认执行深拷贝,并支持浅拷贝
  • 可定制:你可以实现自定义转换方法
  • 在生成转换方法时如果有以下情况会提供清晰的错误提示:
    • 目标结构体有未映射的字段
    • 类型转换会导致信息丢失
  • 包含大量示例的详细文档
  • 经过全面测试

完整示例

1. 定义转换器接口

首先创建一个接口并添加// goverter:converter注释:

package example

// goverter:converter
type Converter interface {
    ConvertItems(source []Input) []Output

    // goverter:ignore Irrelevant
    // goverter:map Nested.AgeInYears Age
    Convert(source Input) Output
}

type Input struct {
    Name string
    Nested InputNested
}
type InputNested struct {
    AgeInYears int
}
type Output struct {
    Name string
    Age int
    Irrelevant bool
}

2. 生成转换代码

运行goverter命令后,它会生成以下转换方法:

package generated

import example "goverter/example"

type ConverterImpl struct{}

func (c *ConverterImpl) Convert(source example.Input) example.Output {
    var exampleOutput example.Output
    exampleOutput.Name = source.Name
    exampleOutput.Age = source.Nested.AgeInYears
    return exampleOutput
}
func (c *ConverterImpl) ConvertItems(source []example.Input) []example.Output {
    var exampleOutputList []example.Output
    if source != nil {
        exampleOutputList = make([]example.Output, len(source))
        for i := 0; i < len(source); i++ {
            exampleOutputList[i] = c.Convert(source[i])
        }
    }
    return exampleOutputList
}

3. 使用生成的转换器

你可以这样使用生成的转换器:

package main

import (
    "fmt"
    "example/generated"
)

func main() {
    converter := &generated.ConverterImpl{}
    
    input := example.Input{
        Name: "John",
        Nested: example.InputNested{
            AgeInYears: 30,
        },
    }
    
    // 转换单个对象
    output := converter.Convert(input)
    fmt.Printf("Converted: %+v\n", output)
    
    // 转换切片
    inputs := []example.Input{input, input}
    outputs := converter.ConvertItems(inputs)
    fmt.Printf("Converted items: %+v\n", outputs)
}

高级用法

自定义映射

你可以使用// goverter:map注释来自定义字段映射:

// goverter:map Nested.AgeInYears Age
Convert(source Input) Output

忽略字段

使用// goverter:ignore注释来忽略目标结构体中的特定字段:

// goverter:ignore Irrelevant
Convert(source Input) Output

版本控制

goverter使用SemVer进行版本控制。

许可证

该项目使用MIT许可证。


更多关于golang通过定义接口自动生成类型转换器插件库goverter的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang通过定义接口自动生成类型转换器插件库goverter的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Goverter: Golang 接口自动类型转换插件库

Goverter 是一个强大的 Go 代码生成工具,它可以根据定义的接口自动生成类型转换器代码,极大简化了不同类型之间的转换工作。

基本概念

Goverter 通过分析你定义的接口来生成转换代码,你只需要描述"要转换成什么",而不需要手动编写具体的转换逻辑。

安装

首先安装 goverter 命令行工具:

go install github.com/jmattheis/goverter/cmd/goverter@latest

基本使用

1. 定义转换接口

创建一个文件 converter.go

//go:generate goverter github.com/jmattheis/goverter/example

package example

// goverter:converter
type Converter interface {
    // goverter:map Address Street
    Convert(source Input) Output
}

type Input struct {
    Name    string
    Age     int
    Address string
}

type Output struct {
    Name  string
    Age   int
    Street string
}

2. 生成转换代码

运行命令:

go generate ./...

这会生成一个 generated/converter.go 文件,包含转换实现。

3. 使用生成的转换器

package main

import (
    "fmt"
    "yourmodule/example"
    "yourmodule/example/generated"
)

func main() {
    converter := generated.NewConverter()
    
    input := example.Input{
        Name:    "John",
        Age:     30,
        Address: "123 Main St",
    }
    
    output := converter.Convert(input)
    
    fmt.Printf("%+v\n", output)
    // 输出: {Name:John Age:30 Street:123 Main St}
}

高级特性

自定义字段映射

// goverter:converter
type Converter interface {
    // goverter:map . FullName
    // goverter:map Age Years
    Convert(source Input) Output
}

嵌套结构转换

type PersonInput struct {
    Name string
    Home AddressInput
}

type PersonOutput struct {
    Name string
    Home AddressOutput
}

type AddressInput struct {
    Street string
}

type AddressOutput struct {
    Street string
}

// goverter:converter
type Converter interface {
    ConvertPerson(source PersonInput) PersonOutput
}

切片和映射转换

// goverter:converter
type Converter interface {
    ConvertUsers([]Input) []Output
    ConvertUserMap(map[string]Input) map[string]Output
}

自定义转换方法

// goverter:converter
type Converter interface {
    // goverter:use . FormatName
    Convert(source Input) Output
    
    // 自定义方法
    FormatName(source Input) string
}

// 实现自定义方法
type impl struct{}

func (c *impl) FormatName(source Input) string {
    return strings.ToUpper(source.Name)
}

忽略字段

// goverter:converter
type Converter interface {
    // goverter:ignore Address
    Convert(source Input) Output
}

配置选项

可以在接口注释中添加配置:

// goverter:converter
// goverter:output:file generated/converter.go
// goverter:output:package generated
// goverter:matchIgnoreCase
type Converter interface {
    // ...
}

实际应用场景

  1. DTO 和领域模型转换:在 API 层和业务层之间转换数据
  2. 数据库模型和业务模型转换:ORM 结果到业务对象的转换
  3. API 版本迁移:不同版本 API 数据结构之间的转换
  4. 微服务间数据交换:服务间通信时的数据格式转换

优势

  1. 类型安全:编译时检查转换规则
  2. 减少样板代码:自动生成转换逻辑
  3. 易于维护:转换规则集中定义
  4. 高性能:生成的代码是直接的赋值操作

Goverter 通过简单的接口定义就能生成复杂的转换逻辑,极大提高了开发效率,特别是在处理大型项目中的多种数据结构转换时尤为有用。

回到顶部