You may use something like this

*        value2 := 
*(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer(&value)) + 8))*
*        if value2 == 0 {*
*                return true*
*        }*

on AMD64, should work also for any 64 bit architecture (at least I believe 
so). Remember though this is hacky and may stop working once.


воскресенье, 23 августа 2020 г. в 22:58:51 UTC+3, Aviv Eyal: 

> I was trying to show that the current behavior is confusing and that 
> fmt.Print() needing to resort to panic-and-recover is kinda code smell, but 
> I sorts-of convinced myself that the current behavior is right, or at least 
> consistent.
>
> In my code, I got bit because I sometimes use v *Type to denote "I may or 
> may not have a value here" (where Type is a value-type). 
> This is probably a bad practice on my behalf, because I break the Liskov 
> substitution principle: there is a value of `*Type` that is not a valid 
> value of `Type`, and I let this value slip by.
>
> In this case, `v Type` implements Stringer (i.e. valid callee for 
> `v.String()`, but `v *Type`, in the strictest sense, does not.
> The only reason we can write:
>
>     func (Type) String() string {...}
>     v *Type = &Type{...}
>     _ = v.String()
>
> and have it compile, is syntactic sugar: `v` gets implicitly 
> de-referenced, and there's an implicit assumption that it's not nil.
> And there's a matching syntactic sugar for converting `Type` to a `*Type`.
>
> So, In the code:
>
>     func (Type) String() string {...}
>
>     v *Type = nil
>     r interface{} = v
>     _, ok = r.(Stringer)
>
> What I really want to ask is "Can I, at runtime, call r.String()?", 
> whereas the question Go answers is "Is any of `r`, `*r`, or `&r` defines 
> .String()?" - which matches the static semantics of `r.String()`.
>
> So, while I should probably not use *Type as a replacement for 
> Optional<Type>, I think it might make sense to have some operator that can 
> determine, at run-time, if a call `r.String()` is valid (including a 
> nil-check).
>
>
> -- Aviv
>
> On Saturday, April 11, 2020 at 4:48:28 PM UTC+3 ren...@ix.netcom.com 
> wrote:
>
>> I agree with the OP. The usefulness of nil interfaces is pretty limited. 
>> Show me a useful case that cant easily be implemented with non-nil 
>> interfaces. 
>>
>> I would argue that allowing nil interfaces causes more subtle latent bugs 
>> and makes it harder to reason about the correctness of code when reviewing 
>> it. 
>>
>> It just feels wrong. I realize I’m probably in the minority here but the 
>> OP is not alone. 
>>
>> On Apr 11, 2020, at 8:20 AM, 'Axel Wagner' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>> On Fri, Apr 10, 2020 at 7:17 PM <cpu...@gmail.com> wrote:
>>
>>> I realize I'm reviving an age-old discussion here and apologize for 
>>> bringing up the undead. I happend to run into this when my application 
>>> panicked when some interfaces where initialized with nil mock objects 
>>> instead of being left uninitialized as in production mode.
>>>
>>
>> Let's imagine a world in which `foo == nil` also is true if `foo` is an 
>> interface-value containing a nil-pointer. Let's say in this world, someone 
>> sends a message to golang-nuts. They wrote a mock for the same code. And 
>> since it's just a mock, they just returned static value from its methods 
>> and didn't need to care if the pointer was nil or not. They are confused, 
>> because the passed in this mock, but the code just assumed the field was 
>> uninitialized and never called into their mock. What would you tell them? 
>> Why is their confusion less valid?
>>
>> This would be an example where a nil implementing fooer is never caught:
>>>
>>> type fooer interface {
>>>  foo()
>>> }
>>>
>>> type other struct{}
>>>
>>> func (o *other) foo() {} // implement fooer
>>>
>>> func main() {
>>>  var f fooer
>>>
>>>  var p *other // nil
>>>  f = p // it is a fooer so I can assign it
>>>
>>>  if f == nil {
>>>     // will not get here
>>>  }
>>> }
>>>
>>>
>>> My confusion comes from the point that the nil interface is apparently 
>>> not "a nil-pointer with the correct method set" while *other is even if nil.
>>>
>>
>> In the code you posted, even a nil *other is a perfectly fine 
>> implementation of fooer. You can call `(*other)(nil).foo()` without any 
>> problems.
>> So, as you illustrated, calling methods on a nil-pointer can be totally 
>> fine. A nil-interface, OTOH, doesn't have any methods to call, as it 
>> doesn't contain a dynamic value. If you write `(*other)(nil).foo()`, it is 
>> completely clear what code gets called - even if that code *might* panic. 
>> If you write `fooer(nil).foo()`, what code should be called in your opinion?
>>
>> I think it's easy to see that a nil-interface and a nil-pointer stored in 
>> an interface are very different things. Even from first principles, without 
>> deep knowledge of the language. And if they are obviously different, I 
>> don't understand why you'd find it confusing that they are not the same in 
>> this particular manner.
>>
>> The above is a case where that might happen. In can be worked around but 
>>> it is unexpected unless the programmer is deeply rooted in the language 
>>> definition.
>>>
>>
>> I fully agree with that. What I *don't* agree with, is where you 
>> attribute the problem here. You say, the problem is that the nil-check is 
>> ill-behaved. I say that - if anything - the original nil-assignment is 
>> ill-behaved. Having `(fooer)((*other)(nil)) == nil` be true is semantically 
>> wrong, because by checking against `nil`, you are checking if you have a 
>> correct implementation - and you might well have a correct implementation, 
>> even if it's using a nil-pointer.
>>
>> Note, that the contained pointer being nil isn't the *only* case in which 
>> calling the method might panic. For example, what about this code?
>> https://play.golang.org/p/lNq0qphez7v
>> Shouldn't the `nil`-check also catch that? After all, calling the method 
>> panics, so it's clearly not a valid implementation - even if x itself is 
>> not nil. Why is a nil-pointer more special than any other value that causes 
>> a method to panic? 
>>
>> Seems as of today that there is no tooling to support that check. Maybe 
>>> it's not a widespread issue.
>>>
>>
>> As of today, the language also isn't changed :) Maybe someone who think 
>> this is important enough to change the language, could also feel it's 
>> important enough to write this tooling.
>>
>>
>>> -- 
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/e0dbcd38-510e-43b9-b363-2af1c636250b%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/e0dbcd38-510e-43b9-b363-2af1c636250b%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> -- 
>> 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...@googlegroups.com.
>>
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEPjcsZ3enqXyt%2BUphFJ1cNQ81cFCcjfwwkQZKHMrjSzA%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEPjcsZ3enqXyt%2BUphFJ1cNQ81cFCcjfwwkQZKHMrjSzA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>>

-- 
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/c1ed2e38-6215-4ed2-8357-f8b5d83bf1a7n%40googlegroups.com.

Reply via email to