Saya cuba guna go-sqlmock
包测试 sql 查询,其中参数之一是 gosnowflake.array
(pada asasnya pembalut hirisan). Biasanya perkara seperti ini memerlukan saya membuat penukar nilai, yang saya sertakan:
func (opt arrayConverterOption[T]) ConvertValue(v any) (driver.Value, error) { casted, ok := v.(*[]T) if ok { Expect(*casted).Should(HaveLen(len(opt.Expected))) for i, c := range *casted { Expect(c).Should(Equal(opt.Expected[i])) } } else { fmt.Printf("Type: %T\n", v) return v, nil } return "TEST_RESULT", nil }
Sekarang, fungsi ini dipanggil untuk setiap parameter yang diserahkan kepada pertanyaan. Saya menggunakan ini untuk menguji bahawa nilai dalam kepingan adalah betul, atau lulus parameter jika tidak. Masalah yang saya hadapi ialah apabila saya mencipta arrayconverteroption[string]
并给它一个 gosnowflake.array(["a", "b", "c"])
作为参数时,类型断言失败,因为gosnowflake.array
返回一个内部动态类型 *stringarray
,它被定义为 *[]string
.
Jadi anda boleh lihat dilema saya di sini. Untuk satu perkara, saya tidak boleh menukar v
因为它是 interface{}
并且我无法为 v
起别名,因为内部类型不是 *[]string
,而是 *stringarray
. Jadi, apa yang perlu saya lakukan di sini?
Saya tidak menemui cara untuk melakukan ini tanpa menyebabkan renungan. Namun, setelah direnung, saya lakukan:
var casted []T var ok bool value := reflect.ValueOf(v) if value.Kind() == reflect.Pointer { if inner := value.Elem(); inner.Kind() == reflect.Slice { r := inner.Convert(reflect.TypeOf([]T{})).Interface() casted, ok = r.([]T) } }
Jadi kod ini secara khusus menyemak mana-mana penuding pada kepingan, iaitu jenis dinamik saya. Ia kemudian menggunakan pantulan untuk menukar objek dalaman kepada jenis kepingan yang saya harapkan. Selepas itu, saya hubungi interface()
以从反射值中获取 interface{}
,然后将其转换为 []t
pada keputusan. Itu sahaja. Jika tidak, maka saya tidak menggunakan salah satu daripada kepingan jenis dinamik ini dan saya boleh mengendalikan jenis itu secara normal.
Atas ialah kandungan terperinci Tukar jenis dinamik peribadi daripada antara muka {}. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!