funcTransformInPlace(slice, function interface{})interface{} { return transform(slice, function, true) }
// map的转换函数,slice为切片,function为对应的函数,inPlace表示是否原地处理 functransform(slice, function interface{}, inPlace bool)interface{} { // 类型判断,必须为切片 sliceInType := reflect.ValueOf(slice) if sliceInType.Kind() != reflect.Slice { panic("transform: not slice") }
// 函数的签名判断,即函数的入参必须和slice里的元素一致 fn := reflect.ValueOf(function) elemType := sliceInType.Type().Elem() if !verifyFuncSignature(fn, elemType, nil) { panic("trasform: function must be of type func(" + sliceInType.Type().Elem().String() + ") outputElemType") }
// 如果是原地,则直接处理函数,结果会保存到入参中(这时入参一般为指针) // 如果非原地,那就需要新建一个切片,用来保存结果 sliceOutType := sliceInType if !inPlace { sliceOutType = reflect.MakeSlice(reflect.SliceOf(fn.Type().Out(0)), sliceInType.Len(), sliceInType.Len()) } for i := 0; i < sliceInType.Len(); i++ { sliceOutType.Index(i).Set(fn.Call([]reflect.Value{sliceInType.Index(i)})[0]) } return sliceOutType.Interface()