Reflect.Values вопросы
При попытке проверить этот бизнес-функции:
//IsInSlice works like Array.prototype.find in JavaScript, except it
// returns -1 if `value` is not found. (Also, Array.prototype.find takes
// function, and IsInSlice takes `value` and `list`)
func IsInSlice(value interface{}, list interface{}) int {
slice := reflect.ValueOf(list)
for i := 0; i < slice.Len(); i++ {
if slice.Index(i) == value {
return i
}
}
return -1
}
Я обнаружил, что он не проходит мои тесты на психику:
func TestIsInSlice(t *testing.T) {
digits := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice := digits[3:8] // returns {3,4,5,6,7}
type args struct {
value interface{}
list interface{}
}
tests := []struct {
name string
args args
want int
}{
{
name: "SanityTest",
args: args{value: 3,
list: []int{3, 4, 5, 6, 7},
},
want: 0,
},
{
name: "ElementAtEnd",
args: args{
value: 5,
list: slice,
},
want: 3,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IsInSlice(tt.args.value, tt.args.list); got != tt.want {
t.Errorf("IsInSlice() = %v, want %v", got, tt.want)
}
})
}
}
Человек, ответственный за исправление этих ошибок, понятия не имеет, что является причиной ошибки, не говоря уже о том, как ее исправить, и ни я, ни старший разработчик. Итак, я попытался выделить проблему, чтобы попытаться ее идентифицировать.
То, что я думал, это было
Когда я регистрировал ошибки, я думал, что они как-то value
сравнивали с reflect.Value
вернулся slice.Index(i)
, Я старался
reflect.DeepEqual(slice.Index(i), value)
но это не удается. Единственный способ пройти тестирование - это использовать Int()
извлечь ценность и использовать
var i int64 = 3
вместо буквального 3
, который является облупленным аф.
В чем проблема и как мы можем это исправить?
2 ответа
Метод Index() возвращает refle.Value. Используйте метод Interface() этого значения, чтобы получить его базовое значение и сравнить с ним:
func IsInSlice(value interface{}, list interface{}) int {
slice := reflect.ValueOf(list)
for i := 0; i < slice.Len(); i++ {
if slice.Index(i).Interface() == value {
return i
}
}
return -1
}
Value.Index()
возвращает reflect.Value
, Сравнивая это с interface{}
вы получите никогда не вернет истину. Вам нужно сравнить с "реальным" значением, используя slice.Index(i).Interface()
,
Тем не менее, вы играете здесь с черной магией. Вы пропускаете много проверок безопасности - что если list
на самом деле это не фрагмент или массив? Что, если value
не того же типа, что и list
элементы? Взгляните на реализацию DeepEqual
чтобы увидеть тип проверок, которые вы можете выполнить для такой функции: https://golang.org/src/reflect/deepequal.go