I’m wondering why *S is not a defined type but S is. Take this example:
package main
import "fmt"
type S struct {}
type SType S // SType and S CANNOT be used interchangeably.
type SPtrType *S // SPtrType and *S CAN be used interchangeably because *S is not a defined type.
func funcPtrS(ptrS *S) { fmt.Printf("funcPtrS's parameter has type: %T \n", ptrS) }
func funcSPtrType(sPtrType SPtrType) { fmt.Printf("funcSPtrType's parameter has type: %T \n", sPtrType) }
func main() {
var s S = S{}
fmt.Printf("s has type: %T \n", s)
var sType SType = SType(s) // Cast necessary because both S and SType are defined types.
fmt.Printf("sType has type: %T \n", sType)
var ptrS *S = &s
fmt.Printf("ptrS has type: %T \n", ptrS)
var sPtrType SPtrType = ptrS // No cast necessary. *S is not a defined type.
fmt.Printf("sPtrType has type: %T \n", sPtrType)
funcPtrS(ptrS)
funcPtrS(sPtrType) // sPtrType is assignable to *S because *S is not a defined type.
funcSPtrType(ptrS) // ptrS is assignable to SPtrType because *S is not a defined type.
funcSPtrType(sPtrType)
}
/*
Output:
s has type: main.S
sType has type: main.SType
ptrS has type: *main.S
sPtrType has type: main.SPtrType
funcPtrS's parameter has type: *main.S
funcPtrS's parameter has type: *main.S
funcSPtrType's parameter has type: main.SPtrType
funcSPtrType's parameter has type: main.SPtrType
*/
These docs say:
A value x
is assignable to a variable of type T
(" x
is assignable to T
") if one of the following conditions applies:
-
x
's type is identical toT
. -
x
's typeV
andT
have identical underlying types and at least one ofV
orT
is not a defined type.
Thus, I can’t assign a variable of type main.S
to a variable of type main.SType
because those two types are both defined types. I can assign a variable of type *main.S
to a variable of type main.SPtrType
and vice versa without casting because *main.S
is not a defined type.
What I don’t understand is why main.S
is a defined type and *main.S
isn’t.
GitHub issue: https://github.com/golang/go/issues/38890