Rumah >pembangunan bahagian belakang >Golang >Mengapakah `json.Unmarshal` dengan Parameter `antara muka{}` Bukan Penunjuk Menghasilkan Keputusan Yang Tidak Dijangka dalam Go?

Mengapakah `json.Unmarshal` dengan Parameter `antara muka{}` Bukan Penunjuk Menghasilkan Keputusan Yang Tidak Dijangka dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-04 20:19:12267semak imbas

Why Does `json.Unmarshal` with a Non-Pointer `interface{}` Parameter Produce Unexpected Results in Go?

Salah Faham Jenis Antara Muka{}: Mendedahkan Kerumitan

Dalam Go, jenis antara muka{} menawarkan kefleksibelan dan kerumitan. Walau bagaimanapun, salah faham sifatnya boleh membawa kepada akibat yang tidak dijangka, seperti yang ditunjukkan oleh contoh yang membingungkan.

Apabila cuba menghantar jenis bukan penunjuk sebagai parameter antara muka{} kepada fungsi dan menggunakan json.Unmarshal dengannya, output boleh mengejutkan. Contoh di bawah menunjukkan tingkah laku ini:

package main

import (
    "encoding/json"
    "fmt"
)

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, &i)
    fmt.Printf("%T\n", i)
}

type Test struct {
    Foo string
}

func main() {
    test(Test{})
}

Output:

main.Test
*interface {}
map[string]interface {}

Menyingkap Misteri

Kekeliruan berpunca daripada sifat antara muka {}. Ia bukan sekadar bekas tanpa taip tetapi pembungkus untuk pasangan (nilai, jenis). Antara muka menyimpan rujukan kepada nilai konkrit dan jenisnya.

json.Unmarshal mengambil nilai antara muka{} sebagai inputnya, jadi kita boleh terus menghantar i kepadanya. Percubaan untuk mengambil alamatnya (seperti dengan &i) adalah tidak perlu.

Penunjuk dan Antara Muka

Walau bagaimanapun, jika i mengandungi nilai bukan penunjuk, json.Unmarshal menghadapi cabaran. Memandangkan pakej tidak boleh menyahmarshal menjadi bukan penuding, ia mencipta nilai baharu antara muka jenis{}. Ini membolehkannya memilih jenis, yang secara lalai untuk memetakan[rentetan]antara muka{}.

Senario Betul

Untuk senario penuding, hantar &i sebagai hujah berfungsi kerana json.Unmarshal menyahrujuk penuding untuk mencari nilai antara muka{} yang mengandungi nilai *Ujian. Penunjuk memastikan bahawa unmarshaling berlaku dalam jenis yang betul.

Kesimpulan

Untuk mengelakkan kekeliruan ini, elakkan daripada menggunakan penunjuk ke antara muka. Sebaliknya, "letak" penunjuk dalam antara muka dan hantarkannya secara terus. Dengan memahami interaksi antara antara muka{} dan penunjuk, pembangun boleh mengelakkan keputusan yang tidak dijangka dan memanfaatkan sistem jenis Go dengan berkesan.

Atas ialah kandungan terperinci Mengapakah `json.Unmarshal` dengan Parameter `antara muka{}` Bukan Penunjuk Menghasilkan Keputusan Yang Tidak Dijangka dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn