package main
 
import (
	"fmt"
)
 
type Stack[T comparable] struct { // comparableは組み込みの比較可能な型のインタフェース
	vals []T
}
 
func (s *Stack[T]) Push(val T) {
	s.vals = append(s.vals, val)
}
 
func (s *Stack[T]) Pop() (T, bool) {
	if len(s.vals) == 0 {
		var zero T
		return zero, false
	}
	top := s.vals[len(s.vals)-1]
	s.vals = s.vals[:len(s.vals)-1]
	return top, true
}
 
func (s Stack[T]) Contains(val T) bool {
	for _, v := range s.vals {
		if v == val {
			return true
		}
	}
	return false
}
 
func main() {
	var s Stack[int] // Stackの要素の型(int)を指定する
	s.Push(10)
	s.Push(20)
	s.Push(30)
	fmt.Println(s.Contains(10)) // true
	fmt.Println(s.Contains(5))  // false
	s.Push("hoge") // ./prog.go:41:9: cannot use "hoge" (untyped string constant) as int value in argument to s.Push
}