This is a creation in Article, where the information may have evolved or changed.
The Go generics feature has been discussed several times in 1, and Andrew Gerrand now adds the proposal to the issue list of Go 2 and tags it as a Go2 tag. This does not mean, of course, to add generics to go, but rather to demonstrate what a complete proposal should look like.
Here's what the proposal says:
Proposal:go should have generics
Author:ian Lance Taylor
Created:january 2011
Last Updated:april 2016
Discussion at https://golang.org/issue/15292
Abstract
Go should support some form of generic programming.
Generic programming enables the representation of algorithms and data
Structures in a generic form, with concrete elements of the code
(such as types) factored out.
It means the ability to express algorithms with minimal assumptions
About data structures, and VICE-VERSA
(Paraphrasing Jazayeri, et al).
Background
Generic arguments in favor of generics
People can write code once, saving coding time.
People can fix a bug in one instance without have to remember to fix it
in others.
Generics avoid boilerplate:less coding by copying and editing.
Generics save time testing Code:they increase the amount of code
That can is type checked at compile time rather than at run time.
Every statically typed language in current use have generics in one
Form or another (even C has generics, where they is called preprocessor macros;
Example).
Existing support for generic programming in Go
Go already supports a form of generic programming via interfaces.
People can write an abstract algorithm this works with any type that
Implements the interface.
However, interfaces is limited because the methods must use specific types.
There is no-method to-write an interface with a, that takes an
Argument of type T, for any T, and returns a value of the same type.
There is no-method to-write an interface with a, that compares,
Values of the same type T, for any T.
The assumptions that interfaces require about the types that satisfy
them is not minimal.
Interfaces is not simply types; They is also values.
There is no-to-use interface types without using interface values,
and interface values aren ' t always efficient.
There is no-to-create a slice of the dynamic type of an interface.
That's, there is no-to-avoid boxing.
Specific arguments in favor of generics in Go
Generics permit Type-safe polymorphic containers.
Go currently has a very limited set of such containers:slices, and
The most of the maps of types.
The Every program can be written using a slice or map.
Look SortInts at the functions, SortFloats SortStrings
Sort package.
Or SearchInts , SearchFloats , SearchStrings .
Or Len the, Less , and methods of the package Swap byName io/ioutil.
Pure boilerplate copying.
The copy and append functions exist because they make slices much
More useful.
Generics would mean that these functions is unnecessary.
Generics would make it possible to write similar functions for maps
and channels, not to mention user created data types.
Granted, slices is the most important composite data type, and that's why
These functions were needed, but other data types is still useful.
It would is nice to being able to make a copy of a map.
Right now, the function can only is written for a specific map type,
But, except-types, the same code works for any map type.
Similarly, it would is nice to being able to multiplex one channel onto
Without has to rewrite the function for each channel type.
One can imagine a range of simple channel manipulators, but they can
Not being written because the type of the channel must be specified
Explicitly.
Generics let people express the relationship between function parameters
and results.
Consider the simple Transform function, calls a function on every
element of a slice, returning a new slice.
We want to write something like
1 |
func Transform (s []Tfunc(t)U) []U |
But this can is expressed in the current Go.
In many Go programs, people only has to write explicit types in function
Signatures.
Without generics, they also has to write them in another place:in the
Type assertion needed to convert from a interface type back to the
Real type.
The lack of static type checking provided by generics makes the code
Heavier.
What we want from generics in Go
Any implementation of generics on Go should support the following.
- Define generic types based on types that is not known until they is instantiated.
- Write algorithms to operate on values of these types.
- Name generic types and name specific instantiations of generic types.
- Use types derived from generic types, as in making a slice of a generic type,
Or conversely, given a generic type known to BES a slice, defining a variable
With the slice ' s element type.
- Restrict the set of types that is used to instantiate a generic type, to
Ensure the generic type is only instantiated with types the
- Required operations.
- Do not require an explicit relationship between the definition of a generic
Type or function and its use. That's, programs should not has to
Explicitly say type T implements generic G.
- Write interfaces that describe explicit relationships between generic types,
As in a method, that takes, parameters, must both be the same unknown type.
- Do not require explicit instantiation of generic types or functions; They
should be instantiated as needed.
The downsides of generics
Generics affect the whole language.
It's necessary to evaluate every a language construct to see how
It'll work with generics.
Generics affect the whole standard library.
It is desirable to has the standard library make effective use of generics.
Every existing package should is reconsidered to see whether it would benefit
from using generics.
It becomes tempting to build generics into the class library at a
Very, as in C + + std::basic_string<char, std::char_traits<char>, std::allocator<char> > .
This have its benefits-otherwise nobody would does it-but it has
Wide-ranging and sometimes surprising effects, as in incomprehensible
C + + error messages.
As Russ pointed out, generics is
A trade off between programmer time, compilation time, and execution
Time.
Go is currently optimizing compilation time and execution time at the
Expense of programmer time.
Compilation time is a significant benefit of Go.
Can we retain compilation time benefits without sacrificing too much
Execution time?
Unless we choose to optimize execution time, operations that appear
Cheap May is more expensive if they use values of generic type.
This is subtly confusing for programmers.
I think this was less important for Go than for some other languages,
As some operations in Go already has hidden costs such as array
Bounds checks.
Still, it would is essential to ensure that the extra cost of using
Values of generic type is tightly bounded.
Go has a lightweight type system.
Adding generic types inevitably makes the type system more complex.
It is essential that the result remain lightweight.
The upsides of the downsides is that Go is a relatively small
Language, and it really is possible to consider every aspect of the
language when adding generics.
At least the following sections of the spec would need to be extended:
Types, type Identity, assignability, type assertions, Calls, type
Switches, for statements with range clauses.
Only a relatively small number of packages would need to be
Reconsidered in light of generics:container/*, sort, flag, perhaps
bytes.
Packages that currently work in terms of interfaces would generally be
Able to continue doing so.
Conclusion
Generics'll make the language safer, more efficient to use, and more
Powerful.
These advantages is harder to quantify than the disadvantages, but
They is real.
Examples of potential uses of generics in Go
- Containers
- User-written hash tables that is compile-time type-safe, rather than
Converting slice keys to string and using maps
- Sorted Maps (Red-black tree or similar)
- double-ended queues, circular buffers
- A Simpler Heap
Keys(map[K]V) []K,Values(map[K]V) []V
- Caches
- Compile-time Type-safe
sync.Pool
- Generic algorithms that work with the these containers in a type-safe the.
- Union/intersection
- Sort, Stablesort, Find
- Copy (a generic container, and also copy a map)
- Transform a container by applying a function--lisp and
mapcar friends
- Math and MATH/CMPLX
- Testing/quick. {
Check,CheckEqual}
- Mixins
- Like
ioutil.NopCloser , but preserving other methods instead of
Restricting to the Passed-in interface (see the ReadFoo variants of
bytes.Buffer)
- Protobuf
proto.Clone
- Eliminate boilerplate when calling sort function
- Generic diff:
func [T] Diff(x, y []T) []range
- Channel operations
- Merge N channels onto one
- Multiplex one channel onto N
- The Worker-pool pattern
- Graph algorithms, for example immediate dominator computation
- Multi-dimensional arrays (not slices) of different lengths
- Many of the packages in Go.text could benefit from it to avoid duplicate
Implementation or APIs for string and []byte variants; many points.
Could benefit need high performance, though, and generics should provide
Benefit
Proposal
I won ' t discuss a specific implementation proposal Here:my hope is
That this document helps show people that generics is worth having
Provided the downsides can be kept under control.
The following documents are my previous generics proposals,
Presented for historic reference. All is flawed in various ways.
- Type functions (June 2010)
- Generalized types (March 2011)
- Generalized types (October 2013)
- Type parameters (December 2013)
Resources
- https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/edit?pref=2&pli=1# Heading=h.vuko0u3txoew
- https://github.com/golang/go/issues/15292