Skip to content

Instantly share code, notes, and snippets.

@lukpueh
Created April 10, 2019 11:29
Show Gist options
  • Save lukpueh/2957c4648d3fa6bf575e280a81e2fe72 to your computer and use it in GitHub Desktop.
Save lukpueh/2957c4648d3fa6bf575e280a81e2fe72 to your computer and use it in GitHub Desktop.
Self-educational go snippet to learn about the empty interface{} type.
// Self-educational go snippet to learn about the empty interface{} type.
// Based on @hvoecking's arbitrary structures traversal gist
// https://gist.github.com/hvoecking/10772475
package main
import (
"fmt"
"reflect"
"strings"
)
// Wrapper function for recursiveNestedToUpper to take and return `interface{}`
// but avoid switching between `reflect` types and `interface` types in each
// recursion.
func NestedToUpper(obj interface{}) interface{} {
return recursiveNestedToUpper(reflect.ValueOf(obj)).Interface()
}
// Recursive function to uppercase all strings in a nested slice of arbitrary
// depth.
func recursiveNestedToUpper(val reflect.Value) reflect.Value {
ret := reflect.New(val.Type()).Elem()
switch val.Kind() {
case reflect.Slice:
ret.Set(reflect.MakeSlice(val.Type(), val.Len(), val.Cap()))
for i := 0; i < val.Len(); i += 1 {
ret.Index(i).Set(recursiveNestedToUpper(val.Index(i)))
}
case reflect.String:
ret.SetString(strings.ToUpper(val.Interface().(string)))
}
return ret
}
func main() {
// Some nested replacing tests
l := []string{"foo"}
l = NestedToUpper(l).([]string)
fmt.Println(l)
ll := [][]string{{"bar"}}
ll = NestedToUpper(ll).([][]string)
fmt.Println(ll)
lll := [][][]string{{{"baz"}}}
lll = NestedToUpper(lll).([][][]string)
fmt.Println(lll)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment