Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 通过reflect.Value.SetString设置新字符串_Go - Fatal编程技术网

Go 通过reflect.Value.SetString设置新字符串

Go 通过reflect.Value.SetString设置新字符串,go,Go,具有以下代码: 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

具有以下代码:

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)
}
func MakeMap(fpt接口{}){
fnV:=reflect.ValueOf(fpt).Elem()
fnI:=reflect.MakeFunc(fnV.Type(),implMap)
fnV.Set(fnI)
}
func implMap(在[]reflect.Value中)(retSlc[]reflect.Value){
fun:=in[0]//要应用于每个字符串元素的函数
str:=in[1]//传递的字符串
//准备创建新的结果字符串,因为go中的字符串是不可变的。
var builder strings.builder
builder.Grow(str.Len())
//将字符串转换为符文片段以实现utf-8兼容性。
extractedString:=[]符文(str.String())
//迭代字符串中的所有符文,并对每个符文应用传递的函数。
对于i:=0;i
我遇到了一头全新的野兽,尽管我努力去理解自然法则 在使用C/C++之后,golang中的可分配性仍然很神秘

从golang docs:我们可以看到,如果CanSet()为false,它将陷入恐慌。
其中,在CanSet()
中,只有当值可寻址且不是通过使用未报告的结构字段获得时,才可以更改该值


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

看起来生成的函数旨在返回修改后的字符串。鉴于此,
main
函数的结尾应该如下所示:

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

fmt.Println(str2)
返回新的sting值,而不是修改生成的函数参数。函数参数不可设置

func implMap(in []reflect.Value) []reflect.Value {
    fun := in[0] // Function to be applied to each of string elems
    str := in[1] // Passed string
    var builder strings.Builder
    builder.Grow(str.Len())
    extractedString := []rune(str.String())
    for i := 0; i < len(extractedString); i++ {
        replaceWrapper := []reflect.Value{reflect.ValueOf(extractedString[i])}
        replaceVal := fun.Call(replaceWrapper)[0]
        builder.WriteRune(replaceVal.Interface().(rune))
    }

    // Previous lines are same as before (without comments).
    // Return result with reflect.Value from builder's string.
    retStr := reflect.ValueOf(builder.String())
    return []reflect.Value{retStr}
}
通过使用字符串简化所有这些。直接映射:

str := "data_人生ってなに_пустота"
str2 := strings.Map(func(s rune) rune { return s + 1 }, str)
fmt.Println(str2)
func MakeMap(fn *func(func(s rune) rune, string) string) {
    *fn = func(mapping func(rune) rune, s string) string {
        return strings.Map(mapping, s)
    }
}
str := "data_人生ってなに_пустота"
str2 := strings.Map(func(s rune) rune { return s + 1 }, str)
fmt.Println(str2)