hi there serta yeagerlop here for infoworld at idg in this episode of smartgo we're going to
look at a long-awaited feature newly introduced in go in version 1.18 i'm talking about generics
or functions that can elegantly accept one of a range of types without needing to be specialized
for each one when go was first introduced it had no concept of generics as might be found in some
other languages the closest thing you had in go was interfaces but interfaces themselves aren't
really a substitute for two generic behaviors with go version 1.18 though now out in beta
the language has a backwards compatible way to make functions except what are called
parameterized types which is the key to making true generic functions
the idea behind a parameterized type is that you can write a function
that doesn't use a specific type but can accept one of a range of types for its inputs
and you can then refer to whatever type has been passed in by way of its own variable the
insides of the function assume that each of the accepted types support a common set of behaviors
and the compiler handles generating the code needed to work with each of the accepted types
we don't have to manually write one version of a function to accept one type and then another
version to accept another type and so on we can write one function to accept them all
let's take a look at a simple example of how this works in previous videos i talked about
the concept of the interface in go an interface typically contains a list of function names in
any type that can implement these methods or names is said to be compatible with or to satisfy that
interface with go 1.18 we use an interface type as the first step towards making a generic function
let's say we want to create a function that accepts integers both 8 and 64-bit and accepts
floats so we create an interface named number the name is arbitrary we can use whatever we want
and we list the types that we want to accept as what's needed to satisfy that interface as we've
done here next we do the creation of the generic function itself and to do this we employ a new
syntax which was introduced in go 1.18 we give the name of the function and then immediately after
that in braces we list the types we accept along with local names used to identify those types
in this case the type we accept is the interface number which we refer to in
the context of the function definition as n now when we write the rest of the function
we can use these open-ended type definitions in place of more closed-ended specific ones
consider the first argument or the only argument really accepted by the function some numbers
that argument is named s and it consists of a slice of things of type n whatever n would
be in any one case so a slice of n64s or a slice of float64s or a slice of in eights would all be
acceptable here since all of those types satisfy the interface that we're using the actual type
that is in use at any one particular time would be passed along to the function under the name n
and likewise when we return something of the same type n it's whatever that is has been passed in
so the idea again is that instead of talking about a specific type we can refer to a whole class
of types generically whatever the type is at any given invocation of the function we can just refer
to it as m the only restriction is that type has to be one of those in this interface number the
body of this function is simple enough it creates a variable total of type n again of whatever type
has been passed in in this context and uses that to hold the total of all of the numbers that have
been passed in the slice and then it returns that total so if we invoke this function and pass it a
slice of in 64s n will be in n64 and all of the operations in the function will be done under
that assumption if we invoke the function using a slice of float64s then n will become a float64
and so on and so forth so the advantages to all of this should be pretty plain we don't have to write
a separate incarnation of a function every time you want to use a different type the operations we
can perform are generic we can write one function that satisfies behaviors for a whole range of
types now if we run this code we will get sums for each one of these slice types that we've passed in
one for n64 one for float 64 and one for bytes or in this case int 8s now if we needed to add
more specialized behaviors within the function for each type we could do that but right now
this example is just meant to show the basic behavior how to define the function and how
to write it in such a way that it will accept this variety of types as is generics are still
quite new to go go 1.18 isn't even out as of this video it's still only available as a beta
so this is a subject we're going to return to future videos in much greater depth as generics
have a lot of untapped possibilities that many go users are looking forward to tapping into
so that's it for this video if you liked it please leave a comment below don't
forget to subscribe to the idg tech talk channel on youtube and for more smart go
and more dev with serdar be sure to join me on facebook youtube and infoworld.com
you