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

251 天前
 Qjues

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

1162 次点击
所在节点    Go 编程语言
5 条回复
hsfzxjy
251 天前
reflect.Type 可作 map key 的,不用转成 string
Qjues
251 天前
@hsfzxjy 可~我去试试
Qjues
250 天前
@hsfzxjy 已修改成 reflect.Type ,感谢
Brau1589
226 天前
这个容器的场景是什么呀 可以介绍一下嘛
Qjues
216 天前
@Brau1589 emmm, 抽象与实现分离。比如获取一个 service
```
container.Get[service.CampaignService]().Execute(arg1)
```
代码层面就可以有抽象 service 接口,和 service 实现,并且可以放在不同的包下。然后在一个统一的地方注册

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/983313

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX