具有以下代码:

func MakeMap(fpt interface{}) {
   fnV := reflect.ValueOf(fpt).Elem()
   fnI := reflect.MakeFunc(fnV.Type(), implMap)
   fnV.Set(fnI)
}

func implMap(in []reflect.Value) (retSlc []reflect.Value) {
   fun := in[0] // Function to be applied to each of string elems
   str := in[1] // Passed string

   // Prepare for creating new result string as strings in go are immutable.
   var builder strings.Builder
   builder.Grow(str.Len())

   // Convert string to slice of runes for utf-8 compatibility.
   extractedString := []rune(str.String())
   // Iterate over all runes in string and apply passed function to each.
   for i := 0; i < len(extractedString); i++ {
       // reflect.Value.Call expects slice of reflect.Values so we pack it
       // into one.
       replaceWrapper := []reflect.Value{reflect.ValueOf(extractedString[i])}
       // As return value is also slice of reflect.Value's, we extract
       // only expected element by [0]
       replaceVal := fun.Call(replaceWrapper)[0]
       builder.WriteRune(replaceVal.Interface().(rune))
   }
   // ##################
   // PANIC - panic: reflect: reflect.flag.mustBeAssignable using unaddressable value
   str.SetString(builder.String())
   // Tried:
   // - creating temporary value,
   // - retStr := reflect.New(reflect.TypeOf(builder.String())), but still cannot use Set()
   // ##################

   retSlc = []reflect.Value{str}
   return
}

func main() {
   var fun func(func(s rune) rune, string) string
   MakeMap(&fun)
   str := "data_人生ってなに_пустота"

   fun(func(s rune) rune {
    return s + 1
   }, str)

   fmt.Println(str)
}

我遇到了一种全新的野兽,尽管我努力理解根据C / C ++的习惯,golang中的可分配性仍然是个谜。

if CanSet() is false.A Value can be changed only if it is addressable and was not obtained by the use of unexported struct fields

[This great article向我解释了很多有关go中的可寻址性,尽管我仍然不确定上面示例中的恐慌如何优雅地解决以及在golang中堆栈和堆如何工作。