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" {