package main

import "fmt"

// section: function
func Keys[K comparable, V any](m map[K]V) []K {
	keys := make([]K, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	return keys
}

// section: function

func main() {
	// section: usage
	// Much cleaner - type safety is maintained
	stringIntMap := map[string]int{"a": 1, "b": 2, "c": 3}
	intStringMap := map[int]string{1: "one", 2: "two", 3: "three"}

	stringKeys := Keys(stringIntMap)
	intKeys := Keys(intStringMap)

	fmt.Printf("String Keys\t Type: %[1]T\tKeys: %[1]v\n", stringKeys)
	fmt.Printf("Int Keys\t Type: %[1]T\tKeys: %[1]v\n", intKeys)

	// No type assertions needed!
	for _, key := range stringKeys {
		fmt.Printf("Key: %s, Value: %d\n", key, stringIntMap[key])
	}
	// section: usage
}
