Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Gantikan medan struktur dengan nilai daripada struktur "bahagian" lain

Gantikan medan struktur dengan nilai daripada struktur "bahagian" lain

WBOY
WBOYke hadapan
2024-02-12 18:30:09968semak imbas

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.

Kandungan soalan

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?

Penyelesaian

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam