Golang — оператор сравнения, не определенный в интерфейсе, преобразованном в float64

#go #comparison #switch-statement #type-conversion

#Вперед #сравнение #оператор переключения #преобразование типа

Вопрос:

Как показано в приведенном ниже коде, я выполняю некоторое переключение типов на interface{} , чтобы выполнить правильное переключение типов — я пытаюсь преобразовать interface{} либо в float64 , либо в string == , а затем сравнить его со значением, однако, при использовании оператора сравнения, отличного от float64 на ‘s, Go жалуется на это при сборке.

Ошибки, которые выдает Go, следующие :-

 invalid operation: (interface {})(val.(float64)) > subval.Value (operator > not defined on interface)
invalid operation: (interface {})(val.(float64)) >= subval.Value (operator >= not defined on interface)
invalid operation: (interface {})(val.(float64)) < subval.Value (operator < not defined on interface)
invalid operation: (interface {})(val.(float64)) <= subval.Value (operator <= not defined on interface)
  

…и это мой код:-

 val:= s.FieldByName(subval.Metric).Interface()
switch val(type) {
case float64, float32, int:
    switch subval.Type {
    case "greater_than":
        if val.(float64) > subval.Value {
            runAction(subval.Action, Config)
        }
    case "greater_than_or_equal_to":
        if val.(float64) >= subval.Value {
            runAction(subval.Action, Config)
        }
    case "equal_to":
        if val.(float64) == subval.Value {
            runAction(subval.Action, Config)
        }
    case "less_than":
        if val.(float64) < subval.Value {
            runAction(subval.Action, Config)
        }
    case "less_than_or_equal_to":
        if val.(float64) <= subval.Value {
            runAction(subval.Action, Config)
        }
    }
case string:
    if subval.Type == "equal_to" {
        if val.(string) == subval.Value {
            runAction(subval.Action, Config)
        }
    }
}
  

Комментарии:

1. Первое: ваше утверждение типа val.(float64) будет паниковать, если val является float32 . Второе: ошибки сравнения, скорее всего, происходят из-за того, что subvalue.Value это не float64 , а некоторые interface{} . Просто покажите полный пример на игровой площадке.

2. 1 для примера игровой площадки. Я добавлю, что следующий пример работает нормально, поэтому проблема, вероятно, в subval.Value том, что это интерфейс.

3. subval.Value действительно был интерфейсом, моя ошибка. Если кто-либо из вас двоих хочет отправить ответ, я с радостью отмечу его как принятый.

Ответ №1:

Вероятно, ваша проблема в том, что subval.Value это interface{} , поэтому оператор сравнения недоступен. Я думаю, что при выполнении сравнения равенства с интерфейсом, сравните базовые типы по байтам, следовательно, == не выдает ошибку.

Комментарии:

1. Есть ли способ решить это? Могу ли я определить операторы для интерфейса?

Ответ №2:

Если кто-то попал сюда, как я, то для него я опишу свою ситуацию следующим образом. Пусть это будет здесь

У меня была похожая проблема. Было необходимо сравнить два целых числа, которые контейнер списка возвращает как интерфейсы.

Я решил это таким образом:

  1. Инициализировал переменную
  2. Присвоил ему значение, которое я возвращаю с помощью fmt.Sprint() — эта функция возвращает переданное значение в виде строки в вашу переменную.
  3. Затем я преобразовал строку в нужный мне тип
  4. И поэтому я смог сравнить эти значения

Например:

 list1.Front().Value > list2.Front().Value // i cant compare it because this 
                                         //  method returns inerfase{}
value1 := fmt.Sprint(list1.Front().Value) // so if you do it this way
value2 := fmt.Sprint(list2.Front().Value) 


// ...CONVERTING TO int's USING func Atoi()
// you can compare these two values
isItTrue := value1 > value2