You need to enable JavaScript to run this app. 如何在Go中通过interface实现支持int和rune类型的泛型栈
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 01:00:01