> Here's a simplified version of the real code: 
> https://go.dev/play/p/8LfgIGhd8GR <https://go.dev/play/p/8LfgIGhd8GR> - it 
> compiles without any issues.
> 
> Yes it compiles. Plenty of buggy Go code will compile. Here is another 
> example <https://go.dev/play/p/ydqRgz9bHc0> of buggy interface-based code 
> which compiles just fine. We can't prevent users from writing buggy code.
This is not a buggy code. This is a buggy language spec.

> It seems in this case, the bug is storing such a value in that interface. The 
> solution is to not do that.
No. The bug is in Go’s spec that treats values and pointers differently when 
coercing values to an interface type.

> Note that in your case, the dynamic value of that interface is not nil. It's 
> a struct value. Structs can not be nil.
Incorrect. Go language allows coercing a struct with an embedded pointer to an 
interface. Spec:
"If S contains an embedded field *T, the method sets of S and *S both include 
promoted methods with receiver T or *T."

> Except that you can not. In my case I have an interface that has the nil data 
> part, and the program crashes because the reflect code doesn't know that I'm 
> accessing the interface.
> The reflect code panics, because you are comparing a struct value to nil. 
> Struct values can not be nil.
No. I’m comparing AN INTERFACE, not a struct. The interface’s provenance is 
_through_ a struct that has an embedded pointer, but this should not matter to 
the code that accepts the interface.

Would you argue that these statements should behave differently: '1 + 1 == 2’ 
and ‘2 == 2’? Because you argue that ‘1 + 1’ is not ‘2’ and should not work 
this way.

> Again, just write different reflect code then.
Which? Go seems to be losing the type of the variable. It’s not possible to say 
“get me a value as THIS interface type”.

> Reflect gives you the capability to write any dynamic check you want. If you 
> want to check that an embedded pointer field is not-nil, then write the 
> reflect code to check for that. I don't really understand what you are trying 
> to check. But you can implement whatever heuristic you want, using reflect.
I’m trying to check that a freaking interface pointer part is nil. That’s it.

> But really, the solution here is not to "check better". It's to not store 
> invalid implementations of an interface in the interface.
I gave you the real example, somewhat simplified.

> There *are* valid uses for this check - json.Unmarshal is one such. But those 
> cases need reflection anyway. So reflect is a far more sensible and flexible 
> way for programmers to implement whatever check they need, than changing the 
> language.
OK. How do I make this check using reflection? I can’t find a way to do it. The 
only way is to use `unsafe` to manually hack into the low-level interface  
representation to extract the pointer part.

> You can check my example, if you remove the nil check and use non-nil 
> parameters, it would work just fine.
> Okay. Then it seems you have your solution - "remove the nil check and use 
> non-nil parameters”.
Not feasible. It would require huge amounts of code in call sites.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/C90A489D-F7C7-435F-AD23-42535CBC4CEC%40gmail.com.

Reply via email to