In diesem Artikel geht es darum, was es bedeutet, Go Generika hinzuzufĂŒgen, und warum wir dies meiner Meinung nach tun sollten. Ich werde auch auf eine mögliche Ănderung in der Architektur der Sprache eingehen, um Generika hinzuzufĂŒgen.
Go wurde am 10. November 2009 veröffentlicht. Weniger als einen Tag spÀter erschien der
erste Kommentar zu Generika . Es werden auch Ausnahmen erwĂ€hnt, die wir der Sprache in Form von Panik hinzugefĂŒgt und Anfang 2010 wiederhergestellt haben.
Seit drei Jahren der Beobachtung war das Fehlen von Generika immer eine Liste von drei Hauptproblemen, die in der Sprache behoben werden mĂŒssen.
Warum werden Generika benötigt?
Was bedeutet das HinzufĂŒgen von Generika und warum wollen wir es?
Um
Jazayeri und andere zu paraphrasieren: Durch Programmieren mit Generika können Sie Funktionen und Datenstrukturen als Generika ohne Typen darstellen.
Was bedeutet das?
Angenommen, wir mĂŒssen die Elemente des Slice in umgekehrter Reihenfolge darstellen. Dies ist keine sehr hĂ€ufige, aber auch nicht so seltene Aufgabe.
Angenommen, wir haben eine Scheibe von ganzen Zahlen.
func ReverseInts(s []int) {
first := 0
last := len(s)
for first < last {
s[first], s[last] = s[last], s[first]
first++
last--
}
}
. . , . , .
func ReverseInts(s []int) {
first := 0
last := len(s) - 1
for first < last {
s[first], s[last] = s[last], s[first]
first++
last--
}
}
1,
last
. .
func ReverseStrings(s []string) {
first := 0
last := len(s) - 1
for first < last {
s[first], s[last] = s[last], s[first]
first++
last--
}
}
ReverseInts
ReverseStrings
, , , . .
Go,
Reverse
, .
.
Python JavaScript . Go , , .
, ++, Java, Rust Swift, .
Go
Go?
, (interface type) , .
sort.Sort
.
, Go â . . , , , .
. . . , , , , , - , . â , , .
, , , - . Go , , , ,
Index
, . , , . -, , map' . Go , . .
-
Reverse
, reflect, . , .
,
Reverse
. . ,
Reverse
, - , , .
, , , Go, . , , , , . .
, , , , . , . , Go . .
Go . , . .
Go
, Go,
Reverse
. . , Go .
open source, , -
Reverse
, .
, «» . «» , . , , ++, , .
Reverse
, , , :
. , , ++.
, Go .
, . Go. , .
, . , . , , , .
Go - : map. , , . , . ,
[]int
, , , .
map' â - , . :
-, , , , map: , , , .
, , - .
,
Reverse
: - , , , . map, , , , .
Go . , .
, , .
Big Rock Candy Mountain, ,
. . , Go . , .
Go , , . , , , . .
, , .
. , .
-,, -. , . , -, - , . -.
- , . , , , . , .
Go. C . .
Go, Go . Go . . , , - .
Go. : , , Go .
, . , , Go.
Gophercon (Robert Griesemer)
Go. , .
Reverse
.
func Reverse (type Element) (s []Element) {
first := 0
last := len(s) - 1
for first < last {
s[first], s[last] = s[last], s[first]
first++
last--
}
}
, .
.
Element
(type parameter). , , , .
, , , .
func ReverseAndPrint(s []int) {
Reverse(int)(s)
fmt.Println(s)
}
(int)
,
Reverse
.
, , , , .
- .
func ReverseAndPrint(s []int) {
Reverse(s)
fmt.Println(s)
}
-
Reverse
ReverseInts
ReverseStrings
, , .
Go , .
, -, - .
Reverse
.
Element
, Go. -, , .
.
func IndexByte (type T Sequence) (s T, b byte) int {
for i := 0; i < len(s); i++ {
if s[i] == b {
return i
}
}
return -1
}
bytes strings
IndexByte
.
b
s
,
s
[]byte
. - bytes strings. , .
,
T
â
[]byte
.
len
, byte.
T
. , , - ,
T
.
Sequence
. .
Sequence
.
contract Sequence(T) {
T string, []byte
}
, :
T
[]byte
. , . .
,
, Gophercon 2018, , . , , . , .
/ . .
,
String
[]string
s
.
func ToStrings (type E Stringer) (s []E) []string {
r := make([]string, len(s))
for i, v := range s {
r[i] = v.String()
}
return r
}
: ,
String
.
,
String
.
Stringer
.
contract Stringer(T) {
T String() string
}
,
T
String
.
,
fmt.Stringer
, ,
ToStrings
fmt.Stringer
. - ,
fmt.Stringer
.
fmt.Stringer
, Go . ,
fmt.Stringer
.
.
type Graph (type Node, Edge G) struct { ... }
contract G(Node, Edge) {
Node Edges() []Edge
Edge Nodes() (from Node, to Node)
}
func New (type Node, Edge G) (nodes []Node) *Graph(Node, Edge) {
...
}
func (g *Graph(Node, Edge)) ShortestPath(from, to Node) []Edge {
...
}
, . . ,
Node
Edges
, ,
Node
.
Edge
Nodes
,
Nodes
,
Edge
.
,
New
,
Graph
,
ShortestPath
Graph
.
, - . .
(Ordered types)
Go
Min
. ,
Max
. ,
Min
, .
Min
, . :
func Min (type T Ordered) (a, b T) T {
if a < b {
return a
}
return b
}
Ordered
,
T
, « », « », .
contract Ordered(T) {
T int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, uintptr,
float32, float64,
string
}
Ordered
â , . , , - . , « ».
, « », , . , Go .
, , , -, . , -, , . - , , .
, , .
Min
(, , ) .
Ordered
, .
func Min (type T contracts.Ordered) (a, b T) T {
if a < b {
return a
}
return b
}
-
, - , . , .
type Tree (type E) struct {
root *node(E)
compare func(E, E) int
}
type node (type E) struct {
val E
left, right *node(E)
}
.
New
.
func New (type E) (cmp func(E, E) int) *Tree(E) {
return &Tree(E){compare: cmp}
}
,
v
, , .
func (t *Tree(E)) find(v E) **node(E) {
pn := &t.root
for *pn != nil {
switch cmp := t.compare(v, (*pn).val); {
case cmp < 0:
pn = &(*pn).left
case cmp > 0:
pn = &(*pn).right
default:
return pn
}
}
return pn
}
, , . , - .
, .
func (t *Tree(E)) Contains(v E) bool {
return *t.find(e) != nil
}
This is the code for inserting a new value.
func (t *Tree(E)) Insert(v E) bool {
pn := t.find(v)
if *pn != nil {
return false
}
*pn = &node(E){val: v}
return true
}
E
. - . , Go, , .
.
var intTree = tree.New(func(a, b int) int { return a - b })
func InsertAndCheck(v int) {
intTree.Insert(v)
if !intTree.Contains(v) {
log.Fatalf("%d not found after insertion", v)
}
}
. - , . -- .
, . , , , . , , .
CL, go/types. , , , . , , .
, -, , . , , . , , - . , .
, , , Go. . , .
â , -, , Go. , â , , , , . , - Go.