-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
StructScan infinite loop #60
Comments
Thanks for the bug report; I only saw the title on my way into work this morning and thought right away "hmm, structscan would choke on circular data structures".
Does this need to be fixed for embedded structs as well, or does the compiler prevent you from doing embedded struct loops? If not, it'l be fixed soon with the api cleanup release. |
If you don't scan non-embedded structs, I don't think the BFS will be necessary. I didn't researched much the way reflection work in Go, but I think that one way or another, each exported field of the struct should be accessible right away with the right RTTI function. It doesn't need to be fixed for embedded structs, as the compiler complains about recursive embedded (see http://play.golang.org/p/Nkz7n-1W6m). |
Okay, excellent. I suspected the compiler might complain. BFS is still sadly required to emulate Go's shadowing rules. Removing the descent into non-embedded fields is going to simplify things quite a lot. There is a pull request for adding embedded struct support to |
I was trying at the same time, but for me the Tags are embedded at the same time… http://play.golang.org/p/PbEtNt_JOh |
Yes but it's backwards; when you scan, you only have the tag name, and you must go and find the field that fits it. |
I think that the |
I'll do some benchmarking to see if |
Access the value's fields by offset should be better, that's right. |
That doesn't do embedded structs (eg: 'age' is not accessible). More and more I'm thinking that sqlx's |
You're right, it doesn't do embedded struct. I didn't saw it… but the Field.Anonymous field can differentiate embedded field from others, so it can be resolved with either a recursion or a stack (as you did). |
Yes, I think it will end up looking a bit like https://github.com/sqs/modl/commit/dae428523dbab11adfed450f45782f5c7152027b |
Exactly. |
And you could call it reflectx. :) |
@wfreeman that was probably a joke but I can't think of a better way to make it live with the regular |
I was actually entirely serious. And willing to help--I'd use it. |
It seems like all sqlx needs is a
sqlx also needs both the values (for named queries) and the addresses (for scanning) of these fields. Can you think of anything else that would be useful? Edit This is all complicated by the |
commit 8aa2977
Lookups by field index are way, way faster than lookups by field name, especially when accessing embedded names. |
Interesting. I tried the FieldByIndex([]int{0,0,0,0}) for the last one and it was slightly slower than doing f = f.Field(0) 4 times, but might be the same in practice. So, are you thinking of caching the indexes? |
It's slightly slower but nowhere near FieldByName:
This is to be expected as there will be some overhead to the iteration that isn't there when just knowing the indexes all up front. Notably it's still nearly twice as fast to descend 4 levels than to get a top level field by name. |
This has all been merged into master now. |
I had a case earlier which made me pull my hair for a full day and half :
Let's say we have the following structs :
When
StructScan
ing, the function tries to establish a field map by exploring the tree of embedded types of the struct. I my case, the exploration never end because of the pointers.This issue bring the following question to my mind : what is the point of exploring non-embedded fields ? It seem rather non-semantic to me…
And independantly, why making a field map and not simply look for the fields as needed when scanning ?
The text was updated successfully, but these errors were encountered: