簡體   English   中英

如何在Go中安全地檢測struct的零值?

[英]How to detect a zeroed value of struct safely in Go?

我試圖為MySQL編寫一個簡單的ORM,如果定義的結構缺少某些字段,則會遇到問題:

type User struct {
    ID        int64
    Username  string
    Password  string
    Email     string
    Comment   string
}

var u = User{Username: "user_0001", Password: "password"}

User的某些字段未提供值,則其值為零值,例如字符串"" ,bool false ,整數0等。

所以我正在使用reflect來獲取字段名稱和值,生成一個SQL以插入行。

INSERT INTO User (Id, Username, Password, Email, Comment) Values (0, "user_0001", "password", , ,)

您可以看到存在一些零值的字符串,如果我檢測到空字符串""並跳過它們,則可能會跳過正常值。

要處理可能為NULL數據庫列,可以按照FriedrichGroße的建議使用指針,也可以使用db包中的Null... sql.NullString ,例如sql.NullString

要使用Null變量,結構應為

type User struct {
    ID        int64
    Username  string
    Password  string
    Email     sql.NullString
    Comment   sql.NullString
}

然后,您可以通過檢查NullString.Valid來檢測設置的值。 使用NullString在於,在打印或編組特殊情況時,您必須添加特殊情況,因為它們沒有實現Stringer接口,也沒有實現MarshalJSONUnmarshalJSON 您還必須記住在設置字符串的值時手動設置NullString.Valid

例如,像

func TestNullString(t *testing.T) {
    s := sql.NullString{}
    t.Log(s)

    s.String = "Test"
    s.Valid = true
    t.Log(s)
}

版畫

null_string_test.go:21: { false}
null_string_test.go:25: {Test true}

要打印NullString您必須改為

func TestNullString(t *testing.T) {
    s := sql.NullString{}
    t.Log(s.String)

    s.String = "Test"
    s.Value = true
    t.Log(s.String)
}

哪些打印:

null_string_test.go:21: 
null_string_test.go:25: Test

您總是可以在表列中插入一個空字符串。 如果真正重要的是要知道零值或完全不存在值之間的差異,則需要使用指針。

type User struct {
    ID        int64
    Username  *string
}

這會將零值更改為nil以便您可以將其與""區別開。 缺點是,這使這種類型的使用不太容易(實踐中通常會忽略nil檢查),並且您必須取消引用該字段才能獲取實際的字符串。

在您的特定示例中,我根本看不出您為什么需要擔心空值。 您不能只在數據庫中插入""並在代碼中強制執行驗證(非空性),而不使用數據庫約束嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM