Skip to content

Instantly share code, notes, and snippets.

@Atavixion
Created January 7, 2024 14:07
Show Gist options
  • Save Atavixion/b566b89b2a6526b3b2548c9c4e5d4337 to your computer and use it in GitHub Desktop.
Save Atavixion/b566b89b2a6526b3b2548c9c4e5d4337 to your computer and use it in GitHub Desktop.
A Tour of Go/Generic types excercise
package main
import "fmt"
// List represents a singly-linked list that holds
// values of any type.
type List[T any] struct {
next *List[T]
val T
}
func (xs *List[T]) String() string {
if xs.next == nil {
return fmt.Sprintf("{ val: %v, next: <nil> }", xs.val)
} else {
return fmt.Sprintf("{ val: %v, next: %s }", xs.val, fmt.Sprint(xs.next))
}
}
func Append[T any](xs *List[T], x T) *List[T] {
if xs.next == nil {
xs.next = NewList(x)
return xs
} else {
// ys is a pointer to xs, so when "moving" the current(ys) pointer down the
// list, we "keep" the original starting pointer in xs
//
// Step by step:
// xs := { val: 3, next: { val: 2, next: <nil> } }
// ys := { val: 3, next: { val: 2, next: <nil> } }
// ys.next = { val: 2, next: <nil> } (== xs.next)
// ys = Append(ys.next, x) (ys = ys.next)
// ys = { val: 2, next: { val: x, next: <nil> } } (== xs.next)
// xs = { val: 3, next: { val: 2, next: { val: x, next: <nil> } } }
ys := xs
ys = Append(ys.next, x)
return xs
}
}
// Create a list with a starting value
func NewList[T any](val T) *List[T] {
xs := new(List[T])
xs.val = val
xs.next = nil
return xs
}
func main() {
xs := NewList(0)
fmt.Println(xs)
for i := 1; i < 5; i++ {
xs = Append(xs, i)
fmt.Println(xs)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment