-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
为什么find函数里必须传入slice的指针呢,slice本身不就是引用类型吗 #7030
Comments
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the |
@espoirr 先给个结论,逻辑上(即Golang的设计来说)来说你都要传指针,当前Golang的实现上你的map可以不传指针。 先解答你的问题,为什么slice是个引用类型,却需要传入指针,而同为引用类型的map却不需要。 然后再说一个概念,从设计上来说,这里不是在传入指针,而是在传入引用(可以看看C#的ref,out等关键字设计,能让你对这些设计上的东西有些了解),也就是约定上这个函数内部可以对传入的变量做修改。假如你传递的并非引用,那实际上约定来说我就不该动你的东西。 然后当前Golang编译上,map传递变量地址我没有找到设计说明(就是保证一定传递的是地址,可能是没有,也可能是我没看到),我个人觉得当前的编译后传递地址的原因是因为map的实现太大了,传递拷贝会影响性能,当然这只是我无知的猜测,不过如果我猜测是对的话,你用map时没有传递引用,实际上也是各undefined behavior,哪天跑不了了也是可能的。 |
仔细看下slice和map的实现. 实际map持有的是指针,指向实现, 传map可以修改原始数据. 而slice并不是, 它实际是数组指针, 这个切片的长度, 容量. 你不传指针的方式进去, 底层无法修改原始数据. 那么你什么也得不到. 找篇传门介绍slice的文章看看原理就很容易明白 |
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the |
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the |
@espoirr 这个理解是错的,从实现上来说,gorm没有修改引用的指向,而是直接在原值上做了更改(通过反射的方式,根据指针找到了slice这个结构体的地址并操作原值修改,就算底层用了Assign,实际编译结果也是找到原值做修改)。 var a []int // 你认为这个是个指针类型,等同于指针
methodCall(a) // 你认为这里应该传入自动传入指指针 实际上slice编译后是这样 var a struct { // 实际上这里是个结构体类型
Data uintptr
Len int
Cap int
}
methodCall(a) // 你传入的是个结构体 这种从“实现”上说明的方式,可能你会好理解一点。 然后对于map来说 var m map[string]interface{} //这里是声明了一个hmap的指针,看makemap函数返回值(https://github.com/golang/go/blob/22344e11f27d9667e7bbb6209df59e9a9e976d91/src/runtime/map.go#L297)
methodCall(m) // 传入的是个 *hmap指针 实际实现长这样 var m *hmap // 这个是个指针类型
methodCall(m) 但是如果我上面说的,不要过多去关注实现上的东西,而是去关注设计上的东西。 |
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the |
slice本来就是引用类型,为什么还需要传入指针
var students []dao.Student
db.Find(students)
这样写会爆错
var students []dao.Student
db.Find(&students)
这也就不会
但是map就可以不传指针
result := map[string]interface{}{}
db.Model(&dao.Student{}).Find(result)
map和slice同为引用类型,为什么find函数中使用方式却不同
The text was updated successfully, but these errors were encountered: