go-gorm / gorm

The fantastic ORM library for Golang, aims to be developer friendly
https://gorm.io
MIT License
36.91k stars 3.93k forks source link

泛型支持 #4944

Open helphi opened 2 years ago

helphi commented 2 years ago

Your Question

golang 1.18 泛型beta版已出,请问何时发布 gorm 3.0

Expected answer

跟随golang1.18发布

FlameMida commented 2 years ago

只能说期待了

zhuying412 commented 2 years ago

有任何消息吗?

a631807682 commented 2 years ago

Gorm uses a lot of reflection and uses different logic under different parameter types, it is not suitable for using templates. So the question is, how should we modify the API so that generics can bring benefits to users?

helphi commented 2 years ago

eg.

before

var user User
db.First(&user)

after

user := db.First[User]()
jinzhu commented 2 years ago

eg.

before

var user User
db.First(&user)

after

user := db.First[User]()

But with the new style, you can't reuse a variable to reduce GC.

helphi commented 2 years ago

我觉得这个就要看用户在使用过程中如何取舍了,泛型这么多年才出来官方本来也是在性能与便捷之间进行取舍,gorm支持泛型至少表示我们还是跟着主旋律走的噻 ...

jinzhu commented 2 years ago

There is no doubt, we will support generics, but for the above change, I don't see much value, especially it is a breaking changes.

helphi commented 2 years ago

我这里只是随便举的一个例子,表示gorm看能不能通过泛型让大家少写点代码,不能当真,最终肯定要根据实际情况来噻。

zhuying412 commented 2 years ago

Is there a roadmap or scheme about supporting generics?

a631807682 commented 2 years ago

I don't think generics are needed from the current api design, like database/sql and encoding/json. At the moment I haven't figured out how to use generics to make the new api more user-friendly, any suggestions?

yafeng-Soong commented 2 years ago

大家可以看看我搞的泛型分页封装示例,风格类似MyBatis-plus,博客https://juejin.cn/post/7078279187471679518,代码https://github.com/yafeng-Soong/blog-example/tree/main/gorm_page_generic 希望能有所帮助

Hey Guys,I wrote a simple example using generic, the style looks like Java's MyBatis-plus. blog——https://juejin.cn/post/7078279187471679518, Code——https://github.com/yafeng-Soong/blog-example/tree/main/gorm_page_generic Hope to help you.

a631807682 commented 2 years ago

The reason why pagination can use generics is that they have the same logic. Take db.Find as an example, the model of each user cannot be the same, so we use reflection, of course we can convert everything into generics like this, but is it better?

// Find
func Find[T interface{}]() ([]T, error) {
    ...
}

users, err := Find[User]()

// Unmarshal
type GenericsJSon[T interface{}] struct {
}

func (g GenericsJSon[T]) Unmarshal(data []byte) (*T, error) {
    ...
}

user, err := GenericsJSon[User]{}.Unmarshal([]byte(`{"name":"abc"}`))

For me, there are some API that can use generics like Offset/Limit/Count..., but others need to be discussed.

yafeng-Soong commented 2 years ago

The reason why pagination can use generics is that they have the same logic. Take db.Find as an example, the model of each user cannot be the same, so we use reflection, of course we can convert everything into generics like this, but is it better?

// Find
func Find[T interface{}]() ([]T, error) {
  ...
}

users, err := Find[User]()

// Unmarshal
type GenericsJSon[T interface{}] struct {
}

func (g GenericsJSon[T]) Unmarshal(data []byte) (*T, error) {
  ...
}

user, err := GenericsJSon[User]{}.Unmarshal([]byte(`{"name":"abc"}`))

For me, there are some API that can use generics like Offset/Limit/Count..., but others need to be discussed.

Thanks for your reply! I got it.

cheerego commented 2 years ago

https://github.com/cheerego/gorm-generics

看看这个