I am writing some demonstration code that creates a Stack interface and then creates two concrete structures LinkedStack and ArrayStack that implement the interface.
I have a New() function for each concrete type that returns a new instance of each, properly initialized.
I would like to have a function “Union” that takes two Stacks and returns a new Stack containing the contents of both. If I hard-code the Union function to return a LinkedStack, this works fine. I can use my New() function for the LinkedStack, populate it, and return the new instance.
But what I’d -really- like is to create a new instance of whichever Stack type was passed as the first argument. The problem here is figuring out which New() function to call. Is there a way to do this?
Thanks! This doesn’t seem to work in my case, possibly because I’m also using generics:
func Append[S2 Stack[T], S1 Stack[T], T any](s1 S1, s2 S2) S1 {
var result S1
switch result.(type) {
case LinkedStack[T]:
result := NewLinked[T]()
case ArrayStack[T]:
result := NewArray[T]()
default:
panic("Unsupported Type")
}
return result
}
This gives: cannot use type switch on type parameter value result (variable of type S1 constrained by Stack[T])
func Append[S2 Stack[T], S1 Stack[T], T any](s1 S1, s2 S2) S1 {
var result S1
switch any(result).(type) {
case LinkedStack[T]:
result := NewLinked[T]()
case ArrayStack[T]:
result := NewArray[T]()
default:
panic("Unsupported Type")
}
return result
}
Thanks! The any() trick is neat. Still gives me errors, though:
stack/stack.go:127:13: cannot use NewLinked[T]() (value of type LinkedStack[T]) as S1 value in assignment
stack/stack.go:129:13: cannot use NewArray[T]() (value of type ArrayStack[T]) as S1 value in assignment
func Append[S2 Stack[T], S1 Stack[T], T any](s1 S1, s2 S2) S1 {
var result S1
switch any(result).(type) {
case LinkedStack[T]:
result = any(NewLinked[T]()).(S1)
case ArrayStack[T]:
result = any(NewArray[T]()).(S1)
default:
panic("Unsupported Type")
}
return result
}
(Also – this taught me an amazing amount about how type inference and generics work in Go. I’m still going to need to digest it a bit, but I really, really appreciate your help!)