Gorm - 使用指针时如何访问可为空的字段?

Gorm - how to access nullable fields when using pointers?

我是 Go 的新手,仍在学习可选的结构字段。

我正在查看 Gorm 手册页,其中提供了使用指针指示可为空字段的示例 (here)

如果我删除给出的示例,使其仅包含一个必填字段和一个可选字段,我将得到如下内容:

https://play.golang.com/p/lOLGWNVvq1l :

package main

import "fmt"

type User struct {
  Name         string
  Email        *string
}

func main() {
    user := User{Name: "Example"}
    
    // cannot use "example@example.com" (untyped string constant) as *string value in assignment
    user.Email = "example@example.com"
    
    // invalid operation: user.Email == "example@example.com" (mismatched types *string and untyped string)
    if user.Email == "example@example.com" {
       fmt.Println("foo")
    }
}

如何对刚从数据库中检索到的记录执行操作?

我需要能够检查是否为可为空的字段设置了某个值。我也不能给它赋值。

我想到的一种方法是使用某种包装函数来尝试使事情更安全,例如在 https://play.golang.com/p/4YlpPwaXMkm 我有:

func UnwrapString(x *string) string {
    if x != nil {
        return *x
    }
    return ""
}

func WrapString(x string) *string {
    return &x
}

func main() {
    user := User{Name: "Example"}

    // can safely set an optional value that is currently null
    if UnwrapString(user.Email) == "example@example.com" {
        fmt.Println("hello world")
    }
    
    // can safely set a value if the existing Email is null
    user.Email = WrapString("example@example.com")
    
    // only safe because the value is set
    if *user.Email == "example@example.com" {
        fmt.Println("hello world")
    }
}

在 Gorm 中使用可为空的字段似乎是一件非常基本和常见的事情,我不希望自己动手。 Gorm 惯用的方法是什么?

检查字段是否为 non-nil 的惯用方法,如果是,比较值:

if user.Email != nil && *user.Email == "example@example.com" {
  fmt.Println("foo")
}

即使 user.Email 为 nil(并且你不会得到 nil-pointer 取消引用恐慌),这个工作的原因是因为 Go 有短路评估,这意味着如果第一次比较失败AND 语句,第二个不会被计算,因为如果第一个值已经是 false,这个 AND 语句永远不会为真。

做内联指针赋值,你写的函数我也会做:

func StrPtr(s string) *string {
  return &s
}

然后你可以这样做:

user.Email = StrPtr("example@example.com")