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.