Golang - сумма интерфейса [...] {} - PullRequest
0 голосов
/ 27 февраля 2019

Я создал общую структуру данных с именем и универсальным массивом в Golang.

package main

import "fmt"

type NamedArray struct {
  Name string
  values []interface{}
}

func main() {
  data := [...]int{1, 2, 3, 4, 5}
  interfaced_data := make([]interface{}, len(data))
  for i, v := range data{
    interfaced_data[i] = v
  }
  int_arr := NamedArray{Name: "Int Array", values: interfaced_data}
  fmt.Println(int_arr)
  // fmt.Println(int_arr.Sum()) -- uncomment to run Sum

  data_float := [...]float64{0.1, 0.2, 0.3, 0.4, 0.5}
  interfaced_data_float := make([]interface{}, len(data_float))
  for i, v := range data_float{
    interfaced_data_float[i] = v
  }
  float_arr := NamedArray{Name: "Float Array", values: interfaced_data_float}
  fmt.Println(float_arr)
  // fmt.Println(int_arr.Sum()) -- uncomment to run Sum
}

Теперь я хочу определить метод, который позволяет мне суммировать все значения в массиве.Я знаю, что они числовые (хотя int или float зависит от контекста), но у меня возникли серьезные проблемы.

func (arr NamedArray) Sum() interface{} {
  data := arr.values
  sum := 0
  for i, v := range data {
    sum += v
  }
  return sum
}

Хотя я не могу заставить это работать.Когда я раскомментирую строки 18 и 27 (fmt.Println(int_arr.Sum() и fmt.Println(int_arr.Sum()) и пытаюсь запустить код, я получаю

34:9: invalid operation: sum += v (mismatched types int and interface {})

во время компиляции.

Кто-нибудь знает, как добавить универсальные типы, если мы знаем, что они числовые?

Спасибо!

1 Ответ

0 голосов
/ 27 февраля 2019

Оператор + не определен для значений типа interface{}.Вы должны получить значение типа int из значений interface{}, прежде чем сможете работать с ним как с числом.

Для этого вы можете использовать утверждение типа .См. Этот пример:

s := []interface{}{1, 2, 3, "invalid"}

sum := 0
for _, v := range s {
    if i, ok := v.(int); ok {
        sum += i
    } else {
        fmt.Println("Not int:", v)
    }
}
fmt.Println("Sum:", sum)

Вывод (попробуйте на Go Playground ):

Not int: invalid
Sum: 6

В приведенном выше примере обрабатываются только int чисел и ничегоостальное.Если вы хотите «поддерживать» несколько типов чисел, более удобным способом было бы использовать переключатель типа :

s := []interface{}{1, int32(2), int8(3), "invalid"}

sum := 0
for _, v := range s {
    switch i := v.(type) {
    case int:
        sum += i
    case int32:
        sum += int(i)
    case int8:
        sum += int(i)
    default:
        fmt.Println("Not int:", v)
    }
}
fmt.Println("Sum:", sum)

Вывод одинаков.Попробуйте это на Go Playground .

...