// UpsertByDwIndicatorID 创建或者更新,返回最新的数据
func UpsertByDwIndicatorID(d *model.BiIndicator) error {
var err error
if nil == d || 0 == d.DwIndicatorID {
return errors.New("UpsertByDwIndicatorID error: BiIndicator nil or DwIndicatorID value is empty")
}
if _, err := QueryOne([]basemodel.Pair{
{K: "dw_indicator_id", V: d.DwIndicatorID},
}); err != nil {
if err == gorm.ErrRecordNotFound {
return Insert(d)
}
return err
}
if err := UpdateByDwIndicatorID(d); err != nil {
return nil
}
// note
f, err := QueryOne([]basemodel.Pair{
{K: "dw_indicator_id", V: d.DwIndicatorID},
})
*d = *f
fmt.Printf("\n\ndddd UpsertByDwIndicatorID:%+v", d)
return err
}
package main
import "fmt"
type Bird struct {
Age int
Name string
}
func passP(b *Bird) {
b.Age++
b.Name = "Great" + b.Name
fmt.Printf("传入修改后的Bird:\t %+v, \t内存地址:%p, 指针的内存地址: %p\n", *b, b, &b)
}
func main() {
parrot := &Bird{Age: 1, Name: "Blue"}
fmt.Printf("原始的Bird:\t\t %+v, \t\t内存地址:%p, 指针的内存地址: %p\n", *parrot, parrot, &parrot)
passP(parrot)
fmt.Printf("调用后原始的Bird:\t %+v, \t内存地址:%p, 指针的内存地址: %p\n", *parrot, parrot, &parrot)
}
运行后输出结果:
原始的Bird: {Age:1 Name:Blue}, 内存地址:0xc420076000, 指针的内存地址: 0xc420074000
传入修改后的Bird: {Age:2 Name:GreatBlue}, 内存地址:0xc420076000, 指针的内存地址: 0xc420074010
调用后原始的Bird: {Age:2 Name:GreatBlue}, 内存地址:0xc420076000, 指针的内存地址: 0xc420074000
可以看到在函数passP中,参数p是一个指向Bird的指针,传递参数给它的时候会创建指针的副本(0xc420074010),只不过指针0xc420074000和0xc420074010都指向内存地址0xc420076000。 函数内对*T的改变显然会影响原始的对象,因为它是对同一个对象的操作。
当然,一位对Go有深入了解的读者都已经对这个知识有所了解,也明白了T和*T作为参数的时候副本创建的不同。