如何在Go中通过interface实现支持int和rune类型的泛型栈
Go多类型栈实现修复方案
现有代码核心错误
- 语法错误:Go 中空接口的正确写法是
interface{},你代码中所有单独使用的interface都不符合语法规范 - 接口用法错误:接口不能作为方法接收者,接口仅用于定义行为契约,需要由你声明的
intStack、runeStack等具体类型实现接口规定的全部方法 - 方法签名不匹配:你在
expressionStack接口中定义pop()、peek()返回值为interface{},但实际编写的方法返回int,二者签名不一致,不属于合法的接口实现 - 切片操作错误:方法接收者为指针类型时,需要解引用才能修改原切片,否则修改的是指针副本,不会对原栈生效
- 工厂函数逻辑错误:
createStack声明无返回值却写了return语句,同时不能直接返回接口的指针,应该返回实现了接口的具体类型实例
修复后可运行实现(兼容int/rune类型栈)
非泛型版本(兼容所有Go版本)
package main import "math" type ExpressionStack interface { Pop() interface{} GetSize() int Push(item interface{}) Peek() interface{} } type IntStack []int type RuneStack []rune // IntStack 实现 ExpressionStack 接口 func (s *IntStack) GetSize() int { return len(*s) } func (s *IntStack) Pop() interface{} { length := s.GetSize() if length == 0 { panic("Stack is underflown") } item := (*s)[length-1] *s = (*s)[:length-1] return item } func (s *IntStack) Push(item interface{}) { *s = append(*s, item.(int)) } func (s *IntStack) Peek() interface{} { length := s.GetSize() if length == 0 { return -math.MaxInt32 } return (*s)[length-1] } // RuneStack 实现 ExpressionStack 接口 func (s *RuneStack) GetSize() int { return len(*s) } func (s *RuneStack) Pop() interface{} { length := s.GetSize() if length == 0 { panic("Stack is underflown") } item := (*s)[length-1] *s = (*s)[:length-1] return item } func (s *RuneStack) Push(item interface{}) { *s = append(*s, item.(rune)) } func (s *RuneStack) Peek() interface{} { length := s.GetSize() if length == 0 { return rune(-math.MaxInt32) } return (*s)[length-1] } // 工厂函数 func NewIntStack() ExpressionStack { return &IntStack{} } func NewRuneStack() ExpressionStack { return &RuneStack{} } // 测试用例 func main() { intStk := NewIntStack() intStk.Push(1) intStk.Push(2) println(intStk.Peek().(int)) // 输出2 println(intStk.Pop().(int)) // 输出2 println(intStk.GetSize()) // 输出1 runeStk := NewRuneStack() runeStk.Push('a') runeStk.Push('b') println(string(runeStk.Peek().(rune))) // 输出b println(string(runeStk.Pop().(rune))) // 输出b println(runeStk.GetSize()) // 输出1 }
泛型版本(Go 1.18+推荐,无重复代码)
如果你的开发环境支持Go 1.18及以上版本,使用泛型实现更简洁安全,不需要为每个类型重复写方法:
package main import "math" type Stack[T int | rune] []T func (s *Stack[T]) GetSize() int { return len(*s) } func (s *Stack[T]) Pop() T { length := s.GetSize() if length == 0 { panic("Stack is underflown") } item := (*s)[length-1] *s = (*s)[:length-1] return item } func (s *Stack[T]) Push(item T) { *s = append(*s, item) } func (s *Stack[T]) Peek() T { length := s.GetSize() if length == 0 { var zero T switch any(zero).(type) { case int: return any(-math.MaxInt32).(T) case rune: return any(rune(-math.MaxInt32)).(T) } return zero } return (*s)[length-1] } func main() { // int类型栈 intStk := &Stack[int]{} intStk.Push(1) intStk.Push(2) println(intStk.Peek()) // 输出2 println(intStk.Pop()) // 输出2 println(intStk.GetSize()) // 输出1 // rune类型栈 runeStk := &Stack[rune]{} runeStk.Push('a') runeStk.Push('b') println(string(runeStk.Peek())) // 输出b println(string(runeStk.Pop())) // 输出b println(runeStk.GetSize()) // 输出1 }
内容的提问来源于stack exchange,提问作者KP1987
相关产品推荐
相关产品推荐

