日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在處理 JSON 數據時,我們通常會使用 json.Unmarshal 函數將 JSON 字符串解析為 Go 語言中的結構體。然而,在 UnmarshalJSON 函數內部調用 json.Unmarshal 函數可能會導致堆棧溢出的錯誤。這是因為 UnmarshalJSON 函數在解析 JSON 數據時會再次調用自身,從而導致無限循環。為了避免這種情況,我們可以使用 json.Decoder 的 Decode 方法來解析 JSON 數據,而不是直接調用 json.Unmarshal 函數。這樣做可以確保不會造成堆棧溢出的問題,保證代碼的健壯性和性能。

問題內容

我想執行一些額外的步驟來初始化我的實現 UnmarshalJSON 中的數據結構。在該實現中調用 json.Unmarshal(b, type) 自然會導致堆棧溢出。

JSON 解碼器不斷嘗試查找是否有自定義 UnmarshalJSON 實現,然后再次調用 json.Unmarshal

還有其他方法可以做到這一點嗎?只需調用底層默認實現就不會導致此問題?

解決方法

避免這種情況/防止這種情況的一種簡單而常見的方法是使用 type 關鍵字,并使用類型 conversion 來傳遞該類型的值(該值可以如果是您的原始值,則可以進行類型轉換,因為新類型將原始類型作為其基礎類型)。

這是有效的,因為 type 關鍵字創建了一個新類型,并且新類型將具有零個方法(它不會“繼承”基礎類型的方法)。

這會產生一些運行時開銷嗎?否。引用自 規范:轉換:

讓我們看一個例子。我們有一個帶有數字 AgePerson 類型,并且我們要確保 Age 不能為負數(小于 0)。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func (p *Person) UnmarshalJSON(data []byte) error {
    type person2 Person
    if err := json.Unmarshal(data, (*person2)(p)); err != nil {
        return err
    }

    // Post-processing after unmarshaling:
    if p.Age < 0 {
        p.Age = 0
    }
    return nil
}

登錄后復制

測試它:

var p *Person
fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":10}`), &p))
fmt.Println(p)

fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":-1}`), &p))
fmt.Println(p)

登錄后復制

輸出(在 Go Playground 上嘗試):

&{Bob 10}

&{Bob 0}

登錄后復制

當然,相同的技術也適用于自定義封送處理(MarshalJSON()):

func (p *Person) MarshalJSON() ([]byte, error) {
    // Pre-processing before marshaling:
    if p.Age < 0 {
        p.Age = 0
    }

    type person2 Person
    return json.Marshal((*person2)(p))
}

登錄后復制

測試它:

p = &Person{"Bob", 10}
fmt.Println(json.NewEncoder(os.Stdout).Encode(p))
p = &Person{"Bob", -1}
fmt.Println(json.NewEncoder(os.Stdout).Encode(p))

登錄后復制

輸出(在同一個 Go Playground 示例中):

{"name":"Bob","age":10}

{"name":"Bob","age":0}

登錄后復制

一個非常相似的問題是,當您為 fmt 的自定義文本表示定義 String() string 方法時a> 包,并且您想要使用您修改的默認字符串表示形式。在這里閱讀更多相關信息:t 和 *t 之間的區別

分享到:
標簽:overflow 堆棧溢出 字符串解析
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定