V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Qjues
V2EX  ›  Go 编程语言

基于 Golang 泛型实现的简单容器

  •  
  •   Qjues · 2023-10-18 23:59:43 +08:00 · 1302 次点击
    这是一个创建于 394 天前的主题,其中的信息可能已经有所发展或是发生改变。

    golang 1.18 有泛型之后,对业务代码的编写友好很多,可以更方便的实现一些不限类型的通用库。

    最近尝试在 golang 中实现 ddd 的分层抽象,离不开注册和构建概念,如果没有泛型,那就需要很多强制业务代码中的类型转换代码,看起来不太优雅。

    所以拿泛型实现了一个简单的容器,很方便解决了这个问题。

    使用示例

    package main
    
    import "github.com/attson/container"
    
    type Test struct {
    	Name string
    }
    
    func (t Test) Key() string {
    	return t.Name
    }
    
    type I interface {
    	Key() string
    }
    

    为结构体注册一个构建函数

    // 为结构体注册一个构建函数
    container.Register[Test](func() any {
        return Test{
            Name: "test",
        }
    })
    // 通过容器构建实例
    v1 := container.Make[Test]()
    println(v1.Name) // test
    

    为接口注册一个构建函数

    // 为接口注册一个构建函数
    container.Register[I](func() any {
        return Test{
            Name: "test_interface",
        }
    })
    // 通过容器构建实例
    v3 := container.Make[I]()
    println(v3.Key()) // test_interface
    

    在容器中设置一个接口实例

    // 在容器中设置一个接口实例
    container.Set[I](Test{
        Name: "test_interface_set",
    })
    // 通过容器获取实例
    v6 := container.Get[I]()
    println(v6.Key()) // test_interface_set
    

    使用起来简单了很多。(不讨论性能问题,ddd 问题)


    代码实现也比较简单,有兴趣的可以看下,https://github.com/attson/container

    5 条回复    2023-11-23 10:07:49 +08:00
    hsfzxjy
        1
    hsfzxjy  
       2023-10-19 01:18:25 +08:00 via Android
    reflect.Type 可作 map key 的,不用转成 string
    Qjues
        2
    Qjues  
    OP
       2023-10-19 10:46:27 +08:00
    @hsfzxjy 可~我去试试
    Qjues
        3
    Qjues  
    OP
       2023-10-19 20:30:07 +08:00
    @hsfzxjy 已修改成 reflect.Type ,感谢
    Brau1589
        4
    Brau1589  
       2023-11-13 11:09:36 +08:00
    这个容器的场景是什么呀 可以介绍一下嘛
    Qjues
        5
    Qjues  
    OP
       358 天前
    @Brau1589 emmm, 抽象与实现分离。比如获取一个 service
    ```
    container.Get[service.CampaignService]().Execute(arg1)
    ```
    代码层面就可以有抽象 service 接口,和 service 实现,并且可以放在不同的包下。然后在一个统一的地方注册
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1409 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:41 · PVG 01:41 · LAX 09:41 · JFK 12:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.