mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
## 改进内容
- 扩展 `ScanOption`/`StructOption` 结构体,添加 `OmitEmpty bool` 字段:当设置为 true
时,跳过空值(如空字符串、零值等)的赋值;添加 `OmitNil bool` 字段:当设置为 true 时,跳过 nil 值的赋值;
- 添加 `ScanWithOptions` 函数,支持通过 `ScanOption` 参数使用新选项
- 原有的 `Scan` 函数行为完全不变
- 通过 `NewConverter` 创建的转换器也支持新功能
## 使用示例
### 基本用法
```go
type User struct {
Name *string
Age int
Email string
}
type Person struct {
Name string
Age int
Email string
}
user := User{Name: nil, Age: 25, Email: ""}
person := Person{Name: "zhangsan", Age: 0, Email: "old@example.com"}
err := gconv.ScanWithOptions(user, &person, gconv.ScanOption{
OmitEmpty: true,
OmitNil: true,
})
// 结果: person.Name 保持 "zhangsan",person.Age 变为 25,person.Email 保持 "old@example.com"
```
后续可以将`func Scan(srcValue any, dstPointer any, paramKeyToAttrMap
...map[string]string) (err error)`和`func ScanWithOptions(srcValue any,
dstPointer any, option ...ScanOption) (err error)`直接用`func Scan(srcValue
any, dstPointer any, option ...ScanOption) (err
error)`代替,`ScanOption`里已经包含了`paramKeyToAttrMap map[string]string`
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
60 lines
2.4 KiB
Go
60 lines
2.4 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package gconv
|
|
|
|
// Scan automatically checks the type of `pointer` and converts `params` to `pointer`.
|
|
// It supports various types of parameter conversions, including:
|
|
// 1. Basic types (int, string, float, etc.)
|
|
// 2. Pointer types
|
|
// 3. Slice types
|
|
// 4. Map types
|
|
// 5. Struct types
|
|
//
|
|
// The `paramKeyToAttrMap` parameter is used for mapping between attribute names and parameter keys.
|
|
// TODO: change `paramKeyToAttrMap` to `ScanOption` to be more scalable; add `DeepCopy` option for `ScanOption`.
|
|
func Scan(srcValue any, dstPointer any, paramKeyToAttrMap ...map[string]string) (err error) {
|
|
option := ScanOption{
|
|
ContinueOnError: true,
|
|
}
|
|
if len(paramKeyToAttrMap) > 0 {
|
|
option.ParamKeyToAttrMap = paramKeyToAttrMap[0]
|
|
}
|
|
return defaultConverter.Scan(srcValue, dstPointer, option)
|
|
}
|
|
|
|
// ScanWithOptions automatically checks the type of `dstPointer` and converts `srcValue` to `dstPointer`.
|
|
// It is the same as Scan function, but accepts one or more ScanOption values for additional conversion control.
|
|
//
|
|
// When using ScanWithOptions, the term "omit" means that the assignment from the source to the destination
|
|
// is skipped, so the existing value in the destination field is preserved.
|
|
//
|
|
// - option.OmitEmpty, when set to true, skips assignment of empty source values (for example: empty strings,
|
|
// zero numeric values, zero time values, empty slices or maps), preserving any existing non-empty values
|
|
// in the destination.
|
|
//
|
|
// - option.OmitNil, when set to true, skips assignment of nil source values, preserving the existing values
|
|
// in the destination when the source contains nil.
|
|
//
|
|
// Example:
|
|
//
|
|
// type User struct {
|
|
// Name string
|
|
// Email string
|
|
// }
|
|
//
|
|
// dst := &User{Name: "Alice", Email: "alice@example.com"}
|
|
// src := map[string]any{
|
|
// "Name": "",
|
|
// "Email": nil,
|
|
// }
|
|
//
|
|
// // With OmitEmpty and OmitNil, empty and nil values in src will not overwrite dst.
|
|
// err := ScanWithOptions(src, dst, ScanOption{OmitEmpty: true, OmitNil: true})
|
|
func ScanWithOptions(srcValue any, dstPointer any, option ...ScanOption) (err error) {
|
|
return defaultConverter.Scan(srcValue, dstPointer, option...)
|
|
}
|