I'm trying to build an easy to use templating system. Basically I just want to create a slice with different variables ( strings ) and then loop through the slice and replace the markup {{}}
with the actual values. So if the variable 'name
' is onevar
it will look in the template for {{onevar}}
and replace that with the actual value of the variable .
Question: how do I get the variable name? Basically what's in the source code. Is it possible ? I've tried something with reflect but seems I couldn't get it right. See belowg
onevar := "something"
other := "something else"
var msg string
sa := []string{onevar, other}
for _, v := range sa {
vName := reflect.TypeOf(v).Name()
vName = fmt.Sprintf("{{%s}}", vName)
msg = strings.Replace(msg, vName, v, -1)
}
You cannot do such stuff. The slive does not contain the variables but their values, so you cannot get their name. Just use a map.
instead of working with the variable names, you might work with a slice with (string converted) pointers to the variables to reach your original aim:
package main
import "fmt"
import "unsafe"
import "strconv"
func castStr(v *string) string {
return fmt.Sprint(uintptr(unsafe.Pointer(v)))
}
func uncastStr(s string) string {
p, _ := strconv.ParseInt(s, 10, 64)
return *((*string)(unsafe.Pointer(uintptr(p))))
}
func main() {
onevar := "something"
other := "something else"
sa := []string{castStr(&onevar), castStr(&other)}
for _, v := range sa {
fmt.Printf("{{%s}}
", v)
fmt.Printf("%v
", uncastStr(v))
}
//for _, v := range sa {
// vName := fmt.Sprintf("{{%s}}", v)
// msg = strings.Replace(msg, vName, uncastStr(v) -1)
//}
}
(Don't see a problem working with unsafe here because any casting is not being based of uncontrolled content and unsafe.Pointer is only used for reading. Attention!: Have in mind that pointer-values might vary between program runs. Thus, replacing the templates {{xxx}} in a second run of the program might fail. Moreover: that scenario (second run) might be "unsafe" since unrelated memory might be assessed.)