editor php Banana akan memperkenalkan anda cara menggunakan go-yaml untuk mengawal nilai integer ke dalam perenambelasan. go-yaml ialah perpustakaan bahasa Go untuk memproses data format YAML, yang menyediakan API yang ringkas dan mudah digunakan. Untuk menyusun nilai integer kepada perenambelasan, kita boleh menukar integer kepada hirisan bait dahulu dan kemudian gunakan fungsi fmt.Sprintf untuk memformat hirisan bait menjadi rentetan perenambelasan. Akhir sekali, kita boleh menggunakan perpustakaan go-yaml untuk menulis rentetan yang diformatkan ke dalam fail YAML. Kaedah ini mudah dan cekap serta boleh memenuhi keperluan kita. Seterusnya, mari kita lihat lebih dekat pada langkah pelaksanaan khusus.
Saya mempunyai struktur dengan medan integer yang bermakna kepada manusia dalam perwakilan heksadesimal. Contohnya, tetapkan ini kepada medan ID Vendor.
Saya ingin menyimpan data ini ke fail YAML untuk pengeditan manual dan kemudian memuatkannya daripada fail. Setakat yang saya faham, tiada masalah dengan perwakilan heksadesimal nombor dalam YAML itu sendiri, tetapi go-yaml
(我使用 v3
) mengekodkan integer dalam bentuk perpuluhan, dan saya tidak menemui cara biasa untuk menyimpannya dalam bentuk perenambelasan.
Mari ambil kod berikut sebagai titik permulaan:
import ( //... "gopkg.in/yaml.v3" ) type DeviceInfo struct { VendorId uint32 `yaml:"vendorid"` } func main() { deviceInfo := DeviceInfo{VendorId: 0xdeadbeef} yml, err := yaml.Marshal(deviceInfo) if err != nil { log.Fatal(err) } fmt.Println(string(yml)) }
Kod ini menjana YAML dengan nilai perpuluhan:
vendorid: 3735928559
Seterusnya, go-yaml
允许您为自己的类型创建自定义封送拆收器。我这样做了(我故意省略了 fmt.Sprintf()
格式字符串中的 0x
awalan):
type Uint32Hex uint32 func (U Uint32Hex) MarshalYAML() (interface{}, error) { return fmt.Sprintf("%x", U), nil } type DeviceInfo struct { VendorId Uint32Hex `yaml:"vendorid"` } func main() { // the same code }
Kod ini menjana nilai perenambelasan tanpa awalan 0x
(logik buat masa ini):
vendorid: deadbeef
Tetapi jika saya menambah 0x
awalan dalam marshaler tersuai:
func (U Uint32Hex) MarshalYAML() (interface{}, error) { return fmt.Sprintf("0x%x", U), nil }
Nilai dijana dengan betul, tetapi bukannya nombor, ia adalah rentetan:
vendorid: "0xdeadbeef"
Untuk membongkar baris ini menjadi nombor, saya juga terpaksa menulis unmarshaler tersuai. Saya tidak suka penyelesaian ini.
Akhirnya saya mempunyai soalan berikut:
Adakah terdapat cara mudah untuk menjana nombor perenambelasan menggunakan go-yaml
yang saya tidak temui?
Adakah mungkin untuk membuat pengekod tersuai berdasarkan go-yaml
sebagai lanjutan pakej, tanpa mengubah pakej itu sendiri? Bagi saya, cara yang lebih mudah ialah dengan menghantar teg format dalam penerangan struktur, contohnya, seperti ini:
type DeviceInfo struct { VendorId uint32 `yaml:"vendorid,hex"` }
Jika ini memerlukan perubahan pada kod pakej, apakah pendekatan Go terhadap situasi ini? Hanya salin fail pakej ke dalam projek saya, ubah suai mengikut keperluan dan import secara tempatan?
Masalahnya di sini ialah memetik rentetan dalam yaml adalah pilihan, tetapi go-yaml
使用与 JSON 编码器相同的内部架构。这意味着首先处理自定义封送处理,然后完全独立地应用引用逻辑。 deadbeef
没有被引用,但 0xdeadbeef
被引用的原因是因为后者是一个数字。它被引用,这样当它知道它应该是一个字符串时,它就不会意外地被解组为数字,因为您的自定义封送拆收器返回了一个字符串。由于 deadbeef
menggunakan skema dalaman yang sama seperti pengekod JSON. Ini bermakna bahawa marshaling tersuai dikendalikan terlebih dahulu dan kemudian logik petikan digunakan sepenuhnya secara bebas. deadbeef
tidak dirujuk, tetapi sebab mengapa 0xdeadbeef
dirujuk adalah kerana yang terakhir
deadbeef
tidak boleh dibaca sebagai nombor yang sah, petikan tidak diperlukan. Anda boleh melakukan dua perkara: func (U *Uint32Hex) UnmarshalYAML(value *yaml.Node) error { parsed, err := strconv.ParseUint(value.Value, 0, 32) *U = Uint32Hex(parsed) return err }
go-yaml
并修改它。如果您这样做,则不应更改源文件中的导入。相反,您应该将 replace
指令添加到 go.mod
ganti
pada go.mod
seperti ini:
require gopkg.in/yaml.v3 v3.0.1 replace gopkg.in/yaml.v3 v3.0.1 => ../yaml.v3 // Your local path to the fork
Atas ialah kandungan terperinci Bagaimana untuk mengawal nilai integer kepada hex menggunakan go-yaml?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!