2017-02-28 47 views
2

我試圖檢查結構中的字段是否設置爲其零值與reflect.DeepEqual。我們的想法是,如果是的話,我可以給出一個結構標籤像下面的一個默認改變其值:golang DeepEqual和reflect.Zero

type struct { 
    A int `default:"42"` 
} 

我的問題是這樣的:它看起來像reflect.DeepEqual總是返回我false。我想我錯過了一些東西。這裏是什麼,我試圖做一個簡單的例子:

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 
    s := struct{ A int }{0} 
    field := reflect.ValueOf(s).Field(0) 

    fmt.Println(field.Interface()) 
    fmt.Println(reflect.Zero(field.Type())) 

    fmt.Println(reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()))) 
} 

這裏是代碼的去操場以上版本:https://play.golang.org/p/k9VY-2Dc69

我想知道爲什麼DeepEqual在該返回false案件。

謝謝!

回答

1

這裏:

reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type())) 

您正在比較的int值(包裹在interface{}),以reflect.Value類型的值。 reflect.Zero()返回類型爲reflect.Value的值,而不是interface{}

你忘了打電話給Value.Interface()的第二個參數:

reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()).Interface()) 

這將打印true。試試Go Playground

+0

這種快速的回答非常感謝! – jaimelescornichons

+0

我想這個答案比我的好一點。在我的操場上,我做了一個稍微複雜的轉換來獲得一個int,而轉換爲接口是,我認爲這是正確的方式。 –

+1

@BjornRoche如果你打算使用這個數字,'Value.Int()'可能是一個更好的選擇(因爲它處理更多的類型,而類型斷言只有一個),但爲了比較,我會避免它,因爲它總是返回結果作爲'int64'類型的值,即使'Value'中包含的值是'int'類型。把它交給比較會隱式地將它打包回'interface {}',所以沒有意義。 – icza

1

該問題與您使用反射包有關。

field.Interface() 

返回int(包裝在一個interface{}),而

reflect.Zero(field.Type()) 

返回類型reflect.Value的對象。 fmt.Println以相同的方式打印它們,但這並不意味着它們是相同的類型。

看到這個運動場:https://play.golang.org/p/mLcLSV_0vA