Interface and methods

Interface types … An interface type is specified by a list of interface elements. An interface element is either a method or a type element, where a type element is a union of one or more type terms. A type term is either a single type or a single underlying type. Prior to Go 1.18, interfaces were made up strictly of methods. The introduction of generics complicated things significantly. As such, we’ll talk first about methods, and get to the concept of type elements in a few days.


Duck typing

Interface types An interface type defines a type set. A variable of interface type can store a value of any type that is in the type set of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil. InterfaceType = "interface" "{" { InterfaceElem ";" } "}" . InterfaceElem = MethodElem | TypeElem . MethodElem = MethodName Signature .


Variadic functions

Generally speaking, Go doesn’t allow for the use of optional function parameters. But there is one exception, and that’s where variadic functions come into play. Function types The final incoming parameter in a function signature may have a type prefixed with .... A function with such a parameter is called variadic and may be invoked with zero or more arguments for that parameter. Probably the most ubiquitous example of a variadic function would be fmt.


Unparenthesized results

Function types … Parameter and result lists are always parenthesized except that if there is exactly one unnamed result it may be written as an unparenthesized type. But more directly: Function parameters must always be wrapped in parenthesis. Function reults must be wrapped in parenthesis if there is more than one result, or if the result is named. Further, though not clear from this wording in the spec, if there are no results, no parenthesis are required, even though if there are no parameters, they are still required.

Other

10 min watch


Reaction to Disturbed's "Sound of Silence"

My tireless attempt to be a legitimate YouTuber.


Collapsing like function parameters

Yesterday we learned that we may omit function parameter and result names in a function type definition. But this poses a small limitation: Function types … If [the name is] absent, each type stands for one item of that type. What does that mean, exactly? Well, when using named parameters and results, we have the option to omit the type for subesquent arguments of the same type. Here’s an example to make it more clear;


Naming function parameters and results

Function types … Within a list of parameters or results, the names (IdentifierList) must either all be present or all be absent. If present, each name stands for one item (parameter or result) of the specified type and all non-blank names in the signature must be unique. There are several things to unpack here. Let’s start with the most intuitive part: The names of function parameters and results must be unique.

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.


Function types

Go has first-class functions. That is to say, functions are treated as any other data type, and can be passed around as arguments, used as struct field types, etc. Function types A function type denotes the set of all functions with the same parameter and result types. The value of an uninitialized variable of function type is nil. FunctionType = "func" Signature . Signature = Parameters [ Result ] . Result = Parameters | Type .

How-Tos

10 min watch


Use error decorators to simplify your error handling code

Learn to use a custom error type as a decorator to simplify error handling.


Pointers to interfaces

As I mentioned last week, a pointer in Go may have any base type. This includes interfaces. type MyInterface interface { DoStuff() } var x *MyInterface var y *interface{} var z ****interface{ Foo() } Now while these are all valid, they are rarely useful. And this often trips people up. As a rule: Never use a pointer to an interface. There is only one exception of which I am aware. And it’s so unusual, that you can generally just adhere to the above rule.


nil pointers

Yesterday we learned about pointers. But beyond what the spec says, there are a few notes worth calling out. To start with, as mentioned in the spec, the zero value for a pointer is nil. But it’s still a typed nil value, as we can see by using the %T printf argument, which displays the variables type. Expanding on yesterday’s example: var x int var y *int var z **int // Prints: 0 <nil> <nil> <nil> fmt.