выровнять список аргументов, где аргументы могут быть срезами или массивами - PullRequest
0 голосов
/ 21 декабря 2018

Если у меня есть такая функция:

func AcceptsAnything(v ...interface{}){
  args =: FlattenDeep(v);  // flatten any arrays or slices
}

Я пытаюсь реализовать FlattenDeep:

func getKind(v interface{}) string {

    rt := reflect.TypeOf(v)
    switch rt.Kind() {
    case reflect.Slice:
        return "slice"
    case reflect.Array:
        return "array"
    default:
        return "unknown"
    }

}

func FlattenDeep(args ...interface{}) []interface{} {
    list := []interface{}{}

   for _, v := range args {

     kind := getKind(v);

     if kind != "unknown" {
        list = append(list, FlattenDeep(v)...)  // does not compile
     } else{
        list = append(list, v);
       }
    }
   return list;
}

, но я не знаю, как добавить несколько элементов в списокоднажды.Должен ли я просто просмотреть результаты FlattenDeep или есть способ распространить результаты и добавить их в список?

Это может сработать:

func FlattenDeep(args ...interface{}) []interface{} {
    list := []interface{}{}

    for _, v := range args {

        kind := getKind(v);
        if kind != "unknown" {
            for _, z := range FlattenDeep((v.([]interface{})...) {
                list = append(list, z)
            }

        } else {
            list = append(list, v);
        }
    }
    return list;
}

, но я что-то ищучуть менее многословно, если это возможно

1 Ответ

0 голосов
/ 21 декабря 2018

Вот как сгладить произвольные фрагменты и массивы в интерфейсе [] {}:

func flattenDeep(args []interface{}, v reflect.Value) []interface{} {

    if v.Kind() == reflect.Interface {
        v = v.Elem()
    }

    if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            args = flattenDeep(args, v.Index(i))
        }
    } else {
        args = append(args, v.Interface())
    }

    return args
}

func AcceptsAnything(v ...interface{}) {
    args := flattenDeep(nil, reflect.ValueOf(v))
    fmt.Println(args)
}

Запустить его на игровой площадке

Если функция должна обрабатыватьтипы срезов и массивов с произвольным типом элементов, затем приложение должно перебирать срезы или массивы с использованием отражающего API для получения значений в интерфейс [] {}.

Если вам нужно только выровнять [] интерфейс {}, то API отражения не требуется:

func flattenDeep(args []interface{}, v interface{}) []interface{} {
    if s, ok := v.([]interface{}); ok {
        for _, v := range s {
            args = flattenDeep(args, v)
        }
    } else {
        args = append(args, v)
    }
    return args
}

func AcceptsAnything(v ...interface{}) {
    args := flattenDeep(nil, v)
    fmt.Println(args)
}

Запустите его на игровой площадке .

...