Rumah > Artikel > pembangunan bahagian belakang > Gantikan medan struktur dengan nilai daripada struktur "bahagian" lain
editor php Xigua di sini untuk memperkenalkan kepada anda kaedah tentang menggunakan nilai dalam struktur "bahagian" lain untuk menulis ganti medan struktur. Dalam pengaturcaraan, kita sering perlu mengemas kini nilai medan struktur mengikut situasi yang berbeza. Dalam kes ini, kita boleh menulis ganti medan dalam struktur sasaran dengan nilai daripada struktur lain. Kaedah ini sangat praktikal dan boleh meningkatkan kebolehbacaan dan fleksibiliti kod. Seterusnya, saya akan memperincikan cara menggunakan teknik ini untuk memudahkan kod anda dan menjadikannya lebih cekap.
Saya baru dalam Go dan cuba mencipta API CRUD. Harap maafkan saya bahawa pendekatan OOP dalam Go mungkin tidak bijak. Saya mempunyai struktur yang saya mahu kemas kini sebahagiannya melalui titik akhir PATCH.
type Book struct { Id uuid.UUID `json:"id"` Author uuid.UUID `json:"author"` Title string `json:"title"` IsPublic bool `json:"isPublic"` CreatedAt time.Time `json:"createdAt"` UpdatedAt *time.Time `json:"updatedAt"` DeletedAt *time.Time `json:"deletedAt"` }
Saya telah menentukan struct kedua yang mengandungi sifat boleh dikemas kini untuk buku.
type PatchBookDto struct { Author *uuid.UUID Title *string IsPublic *bool }
Dalam kedua-dua struktur, saya menggunakan (mungkin menyalahgunakan?) atribut penunjuk untuk mensimulasikan parameter pilihan. Apa yang saya ingin capai ialah menulis ganti buku dengan mana-mana harta yang diberikan dalam PatchBookDto. Inilah yang saya cuba setakat ini:
var book models.Book // Is taken from an array of books var dto dtos.PatchBookDto if err := c.BindJSON(&dto); err != nil { // Abort } dtoTypeInfo := reflect.TypeOf(&dto).Elem() for i := 0; i < dtoTypeInfo.NumField(); i++ { dtoField := dtoTypeInfo.Field(i) bookField := reflect.ValueOf(&book).Elem().FieldByName(dtoField.Name) if bookField.IsValid() && bookField.CanSet() { dtoValue := reflect.ValueOf(dto).Field(i) if dtoValue.Interface() == reflect.Zero(dtoValue.Type()).Interface() { continue } if dtoField.Type.Kind() == reflect.Ptr { if dtoValue.Elem().Type().AssignableTo(bookField.Type()) { bookField.Set(dtoValue.Elem()) } else { // Abort } } convertedValue := dtoValue.Convert(bookField.Type()) bookField.Set(convertedValue) } }
Apabila saya menguji ini, saya mendapat ralat reflect.Value.Convert: value of type *string Cannot be conversion to type string
.
Adakah sesiapa tahu apa yang saya boleh perbaiki di sini untuk mendapatkan apa yang saya perlukan?
Nampaknya anda berhasrat untuk meletakkan garis panik di blok if dtoField.Type.Kind() ==reflect.Ptr
else.
Cara lain ialah menggunakan penunjuk tidak langsung dan kemudian tetapkan nilainya.
for i := 0; i < dtoTypeInfo.NumField(); i++ { dtoField := dtoTypeInfo.Field(i) bookField := reflect.ValueOf(&book).Elem().FieldByName(dtoField.Name) if bookField.IsValid() && bookField.CanSet() { dtoValue := reflect.ValueOf(dto).Field(i) if dtoValue.Interface() == reflect.Zero(dtoValue.Type()).Interface() { continue } dtoValue = reflect.Indirect(dtoValue) convertedValue := dtoValue.Convert(bookField.Type()) bookField.Set(convertedValue) } }
Atas ialah kandungan terperinci Gantikan medan struktur dengan nilai daripada struktur "bahagian" lain. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!