Reputation: 1216
There is a piece of GO code I have seen in the GIN library and in the Google docs that look like the following
type (
T0 []string
T1 []string
T2 struct{ a, b int }
T3 struct{ a, c int }
T4 func(int, float64) *T0
T5 func(x int, y float64) *[]string
)
What I don't understand is, what this grouping is doing and what are some purposes of this implementation (there wasn't much in the docs that went over this topic unless I missed it)
another example from the gin library
type (
RoutesInfo []RouteInfo
RouteInfo struct {
Method string
Path string
Handler string
}
Engine struct {
RouterGroup
HTMLRender render.HTMLRender
allNoRoute HandlersChain
allNoMethod HandlersChain
noRoute HandlersChain
noMethod HandlersChain
pool sync.Pool
trees methodTrees
RedirectTrailingSlash bool
RedirectFixedPath bool
HandleMethodNotAllowed bool
ForwardedByClientIP bool
}
)
And lastly - sorry this is different topic but related to this one
var _ IRouter = &Engine{}
why is there a _ infront of IRouter? I know it's a blank identifier
but what purpose does it have in that case
Upvotes: 3
Views: 2436
Reputation: 980
Regarding 1st question
The statments shown are type declaration From the Go language spec : A type declaration binds an identifier, the type name, to a new type that has the same underlying type as an existing type, and operations defined for the existing type are also defined for the new type. The new type is different from the existing type.
TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . TypeSpec = identifier Type .
In layman terms, you can do :
type
e.g.
type Temperature uint8
type WeekTemp [7]Temperature
For underlying type, Named instances of the boolean, numeric, and string types are predeclared. Composite types are constructed using type literals
TypeLiteral = ArrayType | StructType | PointerType | FunctionType | InterfaceType | SliceType | MapType | ChannelType .
so you can also equivalently do :
type (
Temperature unit8
WeekTemp [7]Temperature
)
another example for composite type
type Tree struct {
leftChild, rightChild *Tree
}
For 2nd question,
Edited : I wasn't aware of this but trying on go playground , it looks like the answer from jcbwlkr is indeed right.
So trying to compile
type MyInterface interface{
someMethod()
}
type MyType struct{}
var _ MyInterface = &MyType{}
will give this error
cannot use MyType literal (type *MyType) as type MyInterface in assignment: *MyType does not implement MyInterface (missing someMethod method)
So it indeed does a compile time check to make sure that Engine struct conforms to IRouter interface. neat
Upvotes: 1
Reputation: 121049
The code
type (
A int
B string
)
is functionality identical to
type A int
type B string
The grouping is just a way to organize code. The grouping is sometimes used to indicate that the types are related in some way.
The use of the blank identifier is explained in Specs: What's the purpose of the blank identifier in variable assignment?.
Upvotes: 5
Reputation: 7999
I think the first part of your question has already been answered. As for the second part, the code
var _ IRouter = &Engine{}
Creates a compile-time check that *Engine
implements the IRouter
interface. We are assigning a value of type *Engine
to a variable that must be of the type IRouter
. If a *Engine
does not satisfy the interface then it won't compile.
This isn't strictly necessary but some people like to put it in where they define a type to ensure it always satisfies an intended interface.
Upvotes: 4