I’m sure this is a very newbie question and I’m a little hesitant to ask but here it goes…
You often see: x := y.(someType) as the usual form of a type assertion.
Recently, I saw: x := (someType)(nil) .
I can only assume this is a different syntax for a type assertion but I thought I would ask and perhaps this syntax has a special use. When I look at it it seems to be a way of getting a type when you don’t have variable on-hand to cast but perhaps there’s more to it?
One is a type assertion (extracting a value out of an interface box), the other is a conversion (converting a value to another type it’s assignable to).
There’s one thing left of which I am still unsure, if I change the print statement to fmt.Printf("%T", s) I thought it would show a type of t but it shows nil. I get the value is nil but I thought the type would now be t.
So here’s the thing, Go interfaces are sort of like boxes with a value and a type in them. (I’m using loose non-spec terminology here, because that is less confusing to me.) That value and type is always a “concrete” type - that is, a non-interface type like “int” or some struct. You can never put an interface into an interface - you can just take the concrete value out of one interface and put it into another. There are no layers of boxing, just an interface with a concrete value inside it.
What happens in your example is you create a box of type t and it’s empty (the concrete type and value are both nil). When you pass this to Printf, it wants an interface{} (that’s its parameter type). You can’t put an interface into an interface, so your t-typed box is opened and the type and value inside it are put into a new interface{}-typed box. Printf opens this and sees nil type and value, and prints that.