Golang Go语言中 使用 gorm,调用 Create 方式时,传递值对象和引用对象有什么区别

发布于 1周前 作者 ionicwang 来自 Go语言

go<br>package main<br><br>import (<br> "fmt"<br> "<a target="_blank" href="http://gorm.io/driver/sqlite" rel="nofollow noopener">gorm.io/driver/sqlite</a>"<br> "<a target="_blank" href="http://gorm.io/gorm" rel="nofollow noopener">gorm.io/gorm</a>"<br> "time"<br>)<br><br>type User struct {<br> gorm.Model<br> Name string<br> Age int<br>}<br><br>func main() {<br> // 使用 SQLite 内存数据库进行演示<br> db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &amp;gorm.Config{})<br> if err != nil {<br> panic("failed to connect database")<br> }<br> db.AutoMigrate(&amp;User{})<br><br> // 使用引用对象<br> userRef := &amp;User{Name: "John", Age: 25}<br> resultRef := db.Create(userRef)<br> fmt.Printf("Reference Object: %+v\n", userRef)<br> fmt.Printf("RowsAffected: %d\n", resultRef.RowsAffected)<br><br> // 使用值对象<br> userVal := User{Name: "Jane", Age: 30}<br> resultVal := db.Create(&amp;userVal)<br> fmt.Printf("Value Object: %+v\n", userVal)<br> fmt.Printf("RowsAffected: %d\n", resultVal.RowsAffected)<br>}<br>

id 字段均已更新,
Golang Go语言中 使用 gorm,调用 Create 方式时,传递值对象和引用对象有什么区别


更多关于Golang Go语言中 使用 gorm,调用 Create 方式时,传递值对象和引用对象有什么区别的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

在第一个 Create 中使用了引用对象,即使用了已经存在的对象的引用进行数据库操作。这种情况下,GORM 在操作后会更新这个对象的属性,例如在数据库生成的自增 ID 会反映在原始的对象中。

而在第二个 Create 中使用了值对象,即直接使用对象本身进行数据库操作。在这种情况下,GORM 操作数据库后不会更新原始的对象属性。因此,在第二个示例中,userVal 对象的属性不会被更新为数据库生成的值。

– by chatgpt

更多关于Golang Go语言中 使用 gorm,调用 Create 方式时,传递值对象和引用对象有什么区别的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你这俩都是用引用啊,所以没区别

<br><br>import (<br> "fmt"<br><br> "<a target="_blank" href="http://gorm.io/driver/mysql" rel="nofollow noopener">gorm.io/driver/mysql</a>"<br> "<a target="_blank" href="http://gorm.io/gorm" rel="nofollow noopener">gorm.io/gorm</a>"<br>)<br><br>type User struct {<br> gorm.Model<br> Name string<br> Age int<br>}<br><br>func main() {<br> dsn := "root:123456@tcp(127.0.0.1:3306)/go_mysql?charset=utf8mb4&amp;parseTime=True&amp;loc=Local"<br> db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config{})<br> if err != nil {<br> panic("failed to connect database")<br> }<br> db.AutoMigrate(&amp;User{})<br><br> // 使用引用对象<br> userRef := &amp;User{Name: "John", Age: 25}<br> resultRef := db.Create(userRef)<br> fmt.Printf("Reference Object: %+v\n", userRef)<br> fmt.Printf("RowsAffected: %d\n", resultRef.RowsAffected)<br><br> // 使用值对象<br> userVal := User{Name: "Jane", Age: 30}<br> resultVal := db.Create(&amp;userVal)<br> fmt.Printf("Value Object: %+v\n", userVal)<br> fmt.Printf("RowsAffected: %d\n", resultVal.RowsAffected)<br>}<br><br><br><br>Reference Object: &amp;{Model:{ID:1 CreatedAt:2023-11-24 22:50:17.388 +0800 CST UpdatedAt:2023-11-24 22:50:17.388 +0800 CST DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:John Age:25}<br>RowsAffected: 1<br>Value Object: {Model:{ID:2 CreatedAt:2023-11-24 22:50:17.401 +0800 CST UpdatedAt:2023-11-24 22:50:17.401 +0800 CST DeletedAt:{Time:0001-01-01 00:00:00 +0000 UTC Valid:false}} Name:Jane Age:30}<br>RowsAffected: 1<br><br><br><br>

额,,我感觉好像理解的不对嘛,,我试了试



<br>type User struct {<br> // gorm.Model<br> Name string<br> Age int<br>}<br><br>func main() {<br> user := User{Name: "John", Age: 25}<br><br> // 调用接收值的方法<br> changeAge(user)<br> fmt.Println("After changeAge:", user)<br><br> // 调用接收引用的方法<br> changeAge2(&amp;user)<br> fmt.Println("After changeAge2:", user)<br>}<br><br>func changeAge(user User) {<br> // 对 user 进行操作,不会影响原始对象<br> user.Age = user.Age + 1<br> fmt.Println("Inside changeAge:", user)<br>}<br><br>func changeAge2(user *User) {<br> // 对 user 进行操作,会影响原始对象<br> user.Age = user.Age + 1<br> fmt.Println("Inside changeAge2:", *user)<br>}<br><br><br><br>

Inside changeAge: {John 26}
After changeAge: {John 25}
Inside changeAge2: {John 26}
After changeAge2: {John 26}

值,还是,引用,都是自己控制的

假的,我问之前,已经问过 gpt 了。

你仔细看看,主贴写的两次传给 db.Create 的都是 *User 类型

第二次传递过去的,,加了 &,,

yes 大佬。你是对的。

gpt 是对的。

在Golang中使用GORM库进行ORM操作时,特别是在调用Create方法时,传递值对象和引用对象确实存在一些区别,主要体现在数据传递的效率和内存使用上。

  1. 值对象:当你传递一个值对象(即直接传递变量的副本)给Create方法时,GORM会接收到这个值的副本。这意味着,在方法内部对数据的修改不会影响到原始变量。这种方式通常适用于不需要后续修改或较小规模的数据结构,因为它避免了不必要的指针操作,但可能会增加内存开销(因为需要复制整个对象)。

  2. 引用对象:传递引用对象(即指针)给Create方法时,GORM直接操作原始数据的内存地址。这种方式在需要后续修改或数据结构较大时更为高效,因为它避免了数据的复制。同时,通过引用传递还可以让GORM直接操作原始数据,这在某些场景下(如需要返回数据库生成的ID等)更为方便。

总的来说,选择传递值对象还是引用对象,需要根据具体的使用场景来决定。如果数据结构较小且不需要后续修改,传递值对象可能更为简单直接;如果数据结构较大或需要后续修改,传递引用对象则更为高效。在编写代码时,应充分考虑内存使用、性能需求和代码可读性,以选择最合适的传递方式。

回到顶部