Как узнать, является ли переменная произвольного типа нулевой в Golang?

Поскольку не все типы сопоставимы, например. ломтик. Так что мы не можем этого сделать

var v ArbitraryType
v == reflect.Zero(reflect.TypeOf(v)).Interface()

Редактировать — Решение Reflect.DeepEqual

var v ArbitratyType
zero := reflect.Zero(reflect.TypeOf(v)).Interface()
isZero := reflect.DeepEqual(v, zero)

Перейти к документации по reflect.DeepEqual

DeepEqual проверяет глубокое равенство. Он использует нормальное равенство ==, где это возможно, но будет сканировать элементы массивов, срезов, карт и полей структур.


person v1ct0r    schedule 14.10.2015    source источник


Ответы (4)


Смотрите этот пост:

Golang: Reflection - Как получить нулевое значение тип поля

В основном вам нужно иметь особые случаи для несопоставимых типов.

person Peter Noyes    schedule 14.10.2015

Как указывает Питер Нойес, вам просто нужно убедиться, что вы не сравниваете тип, который несопоставим. К счастью, с пакетом reflect это очень просто:

func IsZero(v interface{}) (bool, error) {
    t := reflect.TypeOf(v)
    if !t.Comparable() {
        return false, fmt.Errorf("type is not comparable: %v", t)
    }
    return v == reflect.Zero(t).Interface(), nil
}

См. пример использования здесь.

person joshlf    schedule 14.10.2015

Оба из следующих результатов дают мне разумные результаты (вероятно, потому что они одинаковы?)

reflect.ValueOf(v) == reflect.Zero(reflect.TypeOf(v)))

reflect.DeepEqual(reflect.ValueOf(v), reflect.Zero(reflect.TypeOf(v)))

например различные целые 0 ароматов и неинициализированные struct являются "нулевыми"

К сожалению, пустые строки и массивы — нет. и nil выдает исключение.
Вы можете использовать их в особом случае, если хотите.

person Rhythmic Fistman    schedule 14.10.2015
comment
Привет Rhythmic, Спасибо за ваш ответ! На самом деле == и DeepEqual разные. Согласно документу reflect.DeepEqual, DeepEqual работает как с сопоставимыми, так и с несопоставимыми переменными. - person v1ct0r; 15.10.2015
comment
Я еще не понял сравнимого, я проверю это, спасибо. - person Rhythmic Fistman; 15.10.2015

Go 1.13 представил метод Value.IsZero в пакете reflect. Вот как вы можете проверить нулевое значение, используя его:

if reflect.ValueOf(v).IsZero() {
    // v is zero, do something
}

Помимо основных типов, он также работает для Chan, Func, Array, Interface, Map, Ptr, Slice, UnsafePointer и Struct.

person mrpandey    schedule 18.05.2020