jinzhu / copier

Copier for golang, copy value from struct to struct and more
MIT License
5.58k stars 489 forks source link

嵌套结构体无法使用copier:"-"忽略复制 #222

Open liushuai05 opened 3 weeks ago

liushuai05 commented 3 weeks ago

Reproducible Example

https://go.dev/play/p/tZZ6N4beaTV

Description

嵌套结构体无法使用copier:"-"忽略复制,不嵌套的情况下是可以的参考上面的demo或如下代码片,不知道实现难度如何,但这个可能很有必要大佬,因为很多人写结构体对应数据库都是CreatedAt和UpdateAt什么的只写一次然后采用gorm自动维护,其他地方嵌套进去,但是gorm自动维护好像得是nil才行

这种情况无法忽略,会把source.CreatedAt 复制给target
package main

import (
    "fmt"
    "time"

    "github.com/jinzhu/copier"
)

type Timestamps struct {
    CreatedAt *time.Time `gorm:"type:datetime;not null;default:CURRENT_TIMESTAMP" copier:"-"`
}

type Source struct {
    Timestamps
    Name   string
    Secret string // We do not want this to be copied.
}

type Target struct {
    Timestamps
    Name   string
    Secret string `copier:"-"`
}

func main() {
    var source Source
    source.Name = "John"
    source.Secret = "so_secret"

    times := time.Now()
    source.CreatedAt = &times

    target := Target{}

    copier.Copy(&target, &source)
    fmt.Printf("Name: %s, Secret: '%s' ,CreatedAt:'%s'\n", target.Name, target.Secret, target.CreatedAt)
    // Output: Name: John, Secret: '' ,CreatedAt:'2024-11-07 10:17:43.180809558 +0800 CST m=+0.000030354'
}

下面这种情况就很好

package main

import (
    "fmt"
    "time"

    "github.com/jinzhu/copier"
)

type Source struct {
    CreatedAt *time.Time `gorm:"type:datetime;not null;default:CURRENT_TIMESTAMP" copier:"-"`
    Name   string
    Secret string // We do not want this to be copied.
}

type Target struct {
    CreatedAt *time.Time `gorm:"type:datetime;not null;default:CURRENT_TIMESTAMP" copier:"-"`
    Name   string
    Secret string `copier:"-"`
}

func main() {
    var source Source
    source.Name = "John"
    source.Secret = "so_secret"

    times := time.Now()
    source.CreatedAt = &times

    target := Target{}

    copier.Copy(&target, &source)
    fmt.Printf("Name: %s, Secret: '%s' ,CreatedAt:'%s'\n", target.Name, target.Secret, target.CreatedAt)
    // Output: Name: John, Secret: '' ,CreatedAt:'<nil>'
}