On Thu, Jun 10, 2021 at 2:50 PM Markus Heukelom <[email protected]> wrote:
> Question 1: > > I don't understand when the type assertion succeeds here, as the receiver > for time.Time.String() is (t time.Time), not (t *time.Time). > The method set of `*Time` includes all methods declared on `Time` (but not vice-versa): https://golang.org/ref/spec#Method_sets So even though the receiver of `String() string` is not a pointer, `*Time` still has a `String() string` method. Does this mean that I should read "dynamic type of x" as "the actual type > of x" or the "dereferenced type of x if x is a pointer"? Is there a formal > definition of "dynamic type of x"? Or should I look at a different part of > the spec? > The dynamic type is explained here: https://golang.org/ref/spec#Variables The static type (or just type) of a variable is the type given in its > declaration, the type provided in the new call or composite literal, or the > type of an element of a structured variable. *Variables of interface type > also have a distinct dynamic type, which is the concrete type of the value > assigned to the variable at run time* (unless the value is the > predeclared identifier nil, which has no type). The dynamic type may vary > during execution but values stored in interface variables are always > assignable to the static type of the variable. (emphasis mine) Question 2: > > Accepting that I get "true" on a pointer to a type that implements > fmt.Stringer, how can I check that I can actually safely call > stringer.String()? > You can't. Any Go code might panic. That is, no matter what check you do, the `String()` method could just call `panic("oh well")`. > I.e. how can I prevent the runtime panic? > The, probably unsatisfactory, but only really true answer is "by not assigning a nil `*time.Time` to a `fmt.Stringer` and then call `String()` on that". The runtime panic tells you that your code has a bug. The solution to that is to fix the bug. Note that `time.Time` documents that you shouldn't use it as a pointer in any case. If it's any consolation: Even if there was a check that's correct, remembering to do that check would be just as hard (if not harder) as remembering not to call the method on a nil-pointer or storing a nil-pointer in a `fmt.Stringer` to begin with :) Without using reflection. Please note: I do not mean checking if there is a > nil pointer in x: the error is not raised by the time.String() > implementation, in fact it might work fine with nil pointers were it > defined using a pointer receiver. It seems the error is thrown by the > runtime. > > Thanks, > > Markus > > -- > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/CAMoB8rV%3DQTcHXRC4KvJfcHC9zo8oAE0LR9%3D4ywVb_s-iejX14A%40mail.gmail.com > <https://groups.google.com/d/msgid/golang-nuts/CAMoB8rV%3DQTcHXRC4KvJfcHC9zo8oAE0LR9%3D4ywVb_s-iejX14A%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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfH53Of8mhvyigdXbmYgWfLRujkbWOLM6QheVcqoYqZnZQ%40mail.gmail.com.
