Skip to content

proposal: Go 2: support type generic programming #41847

@auula

Description

@auula

My version of Go are you using (go version)?

$ go version
go version go1.14 darwin/amd64

My proposals and needs:

Hope to support type generics in later versions to improve code writing efficiency.

  • This is an example of the current code
  • My Example Code:
package main

import (
	"fmt"
	"strconv"
)

type StackNode struct {
	Value interface{}
	Next  *StackNode
}

type Stack struct {
	Size     uint
	RootNode *StackNode
}

func NewStack() *Stack {
	return &Stack{Size: 0, RootNode: &StackNode{Value: 0, Next: nil}}
}

func (s *Stack) push(v interface{}) {
	if s.RootNode == nil { // 第一次
		s.RootNode.Next = &StackNode{Next: nil, Value: v}
		return
	}
	next := s.RootNode.Next
	s.RootNode.Next = &StackNode{Next: next, Value: v}
}

func (s *Stack) pop() interface{} {
	var node *StackNode = s.RootNode.Next
	if node == nil {
		return nil
	}
	s.RootNode.Next = node.Next
	return node.Value
}

func bracketMatching(v []rune, symbol []rune) bool {
	stack := NewStack()
	for _, r := range v {
		if r == symbol[0] {
			stack.push(symbol[0])
		}
		if r == symbol[1] {
			if stack.pop() == nil {
				return false
			}
		}
	}
	return stack.pop() == nil
}

func ReversePolishNotation(str []string) int64 {
	stack := NewStack()
	for _, s := range str {
		var result, o1, o2 int64
		switch s {
		case "+":
			o2, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O2", o2)
			o1, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O1", o1)
			result = o1 + o2
			stack.push(strconv.Itoa(int(result)))
		case "-":
			o2, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O2", o2)
			o1, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O1", o1)
			result = o1 - o2
			stack.push(strconv.Itoa(int(result)))
		case "*":
			o2, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O2", o2)
			o1, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O1", o1)
			result = o1 * o2
			stack.push(strconv.Itoa(int(result)))
		case "/":
			o2, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O2", o2)
			o1, _ = strconv.ParseInt(stack.pop().(string), 10, 64)
			fmt.Println("O1", o1)
			result = o1 / o2
			stack.push(strconv.Itoa(int(result)))
		default:
			stack.push(s)
		}

	}

	parseInt, err := strconv.ParseInt(stack.pop().(string), 10, 64)
	if err != nil {
		panic(err)
	}

	return parseInt
}

func main() {
	stack := NewStack()
	stack.push("0")
	stack.push("1")
	stack.push("2")
	stack.push("3")
	stack.push("4")
	stack.push(5)
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	str := []string{"3", "17", "15", "-", "*", "18", "6", "/", "+"}
	fmt.Println(ReversePolishNotation(str))
}

The value type of the above StackNode struct can only be stored through interface{}, but I want to use generics to dynamically implement the type when it is created.

What did you expect to see?

  1. I look forward to supporting generics and simplifying code in Go2.
  2. My generic solution suggestion is that Go has a built-in T type, which replaces the scenarios where we sometimes need to use generics.
  • For example like this:
type StackNode<T> struct {
	Value T // Built-in T type 
	Next  *StackNode
}

// This is the dynamic creation type generic
func NewNode() *StackNode {
	return &StackNode{}<string>;
}
  • Thank you, the above is my idea and proposal

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeLanguageChangeSuggested changes to the Go languageProposalWaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.v2An incompatible library change

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions