Pergi: Bagaimana menggunakan nilai nol tanpa menggunakan tipe referensi



Berdasarkan gambar dari gopherize.me



Cukup sering dari kode Go kita harus bekerja dengan berbagai API HTTP atau bertindak sebagai layanan HTTP sendiri.



Salah satu kasus paling umum: kami menerima data dalam bentuk struktur dari database, mengirim struktur tersebut ke API eksternal, sebagai tanggapan kami menerima struktur lain, entah bagaimana mengubahnya dan menyimpannya ke database.



Dengan kata lain: pemrosesan seperti itu tidak memerlukan banyak operasi terpisah dengan struktur permintaan dan respons.



API , , nil - -nil .



type ApiResponse struct {
  Code *string json:"code"`
}


, , Go escape . β€” GC " ", GC .



:



  • API , nil . , API β€” : -, , - β€” , .
  • Go , nil , .


, " "



.



Go



type pointerSmall struct {
 Field000 *string
 Field001 *string
 Field002 *string
 Field003 *string
 Field004 *string
 Field005 *string
}


,



type valueSmall struct {
 Field000 string
 Field001 string
 Field002 string
 Field003 string
 Field004 string
 Field005 string
}


0 , .

, .



: Go, ( - ) .



β€” . , . . β€” . , .. Go .



β€” , . , .



BenchmarkPointerSmall-8    1000000000          0.295 ns/op        0 B/op        0 allocs/op
BenchmarkValueSmall-8      184702404          6.51 ns/op        0 B/op        0 allocs/op


. , - - .



BenchmarkPointerSmallChain-8    1000000000          0.297 ns/op        0 B/op        0 allocs/op
BenchmarkValueSmallChain-8      59185880         20.3 ns/op        0 B/op        0 allocs/op


JSON . , jsoniter. . , .



BenchmarkPointerSmallJSON-8       49522      23724 ns/op    14122 B/op       28 allocs/op
BenchmarkValueSmallJSON-8         52234      22806 ns/op    14011 B/op       15 allocs/op


, easyjson. , .



BenchmarkPointerSmallEasyJSON-8       64482      17815 ns/op    14591 B/op       21 allocs/op
BenchmarkValueSmallEasyJSON-8         63136      17537 ns/op    14444 B/op       14 allocs/op


: , . (/ ) β€” .



.



type pointerBig struct {
 Field000 *string
 ...
 Field999 *string
}

type valueBig struct {
 Field000 string
 ...
 Field999 string
}


. , 0 , ( , .. ). , :



BenchmarkPointerBig-8       36787      32243 ns/op    24192 B/op     1001 allocs/op
BenchmarkValueBig-8        721375       1613 ns/op        0 B/op        0 allocs/op


. . ( , ).



BenchmarkPointerBigChain-8       36607      31709 ns/op    24192 B/op     1001 allocs/op
BenchmarkValueBigChain-8        351693       3216 ns/op        0 B/op        0 allocs/op


.



BenchmarkPointerBigJSON-8         250    4640020 ns/op  5326593 B/op     4024 allocs/op
BenchmarkValueBigJSON-8           270    4289834 ns/op  4110721 B/op     2015 allocs/op


, easyjson. . , jsoniter.



BenchmarkPointerBigEasyJSON-8         364    3204100 ns/op  2357440 B/op     3066 allocs/op
BenchmarkValueBigEasyJSON-8           380    3058639 ns/op  2302248 B/op     1063 allocs/op


: β€” , . β€” " ". (easyjson ), β€” .





β€” Nullable . sql β€” sql.NullBool, sql.NullString .



Selain itu, untuk jenisnya, Anda perlu menjelaskan fungsi encoding dan decoding.



func (n NullString) MarshalJSON() ([]byte, error) {
    if !n.Valid {
        return []byte("null"), nil
    }

    return jsoniter.Marshal(n.String)
}

func (n *NullString) UnmarshalJSON(data []byte) error {
    if bytes.Equal(data, []byte("null")) {
        *n = NullString{}
        return nil
    }

    var res string

    err := jsoniter.Unmarshal(data, &res)
    if err != nil {
        return err
    }

    *n = NullString{String: res, Valid: true}

    return nil
}


Sebagai hasil dari menyingkirkan jenis referensi di API - saya mengembangkan pustaka nan , dengan jenis Nullable dasar dengan fungsi encoding dan decoding untuk JSON, jsoniter, easyjson, gocql.



Kenyamanan menggunakan tipe Nullable



Dan salah satu pertanyaan terakhir yang dapat Anda tanyakan tentang beralih ke tipe Nullable adalah apakah mereka nyaman digunakan.



Pendapat pribadi saya nyaman, tipe memiliki pola penggunaan yang sama dengan referensi variabel.



Saat menggunakan tautan, kami menulis



if a != nil && *a == "sometext" {


Dengan tipe Nullable, kami menulis



if a.Valid && a.String == "sometext" {



All Articles