例如,我有这段代码:

type MyStruct struct {    
    ...
    MyField *MyOtherStruct
    ...
}

type MyOtherStruct struct {
    ...
    MyOtherField *string
    ...
}

// I have a fuction that receive MyOtherField as parameter
func MyFunc(myOtherField *string) {
    ...
}

// How can I avoid using if/else here
if MyStruct.MyField != nil {
    MyFunc((*MyStruct.MyField).MyOtherField)
} else {
    MyFunc(nil)
}

在我的示例中,我必须使用If Else来处理MyStruct.MyField是否为零.我想找到一种方法来缩短我的代码.

我想找一些像MyFunc(MyStruct.MyField ? (*MyStruct.MyField).MyOtherField : nil)在JavaScript中的方法.

推荐答案

GoLang没有‘Coalescing nil’运算符或三元条件(至少在设计上是这样),但是如果你想从你的主流中删除else,你可以把它提取到一个助手函数中.

我已经将其描述为带有*MyStruct Arg接收器的Func,但它也同样可以作为接受*MyStruct Arg的独立乐趣而存在:

func (ms *MyStruct) getMyOtherFieldOrNil() *string {
   if ms.MyField == nil {
      return nil
   }
   return ms.MyField.MyOtherField
}

Func的名称清楚地表明,空结果是合法的,以避免任何潜在的混淆.

然后,当您需要MyField.MyOtherFieldnil时(当MyFieldnil时),您可以使用这个来代替if {} else {}构造:

    ms := &MyStruct{}

    // ...

    MyFunc(ms.getMyOtherFieldOrNil())

脚注

这与Burak的答案类似,但避免了nil receivers的潜在trap ,我认为这是前面提到的"微妙的错误"的原因.如果在nil*MyStruct接收器上调用这个稍高级别的帮助器函数,则会出现panic (这是应该的),但在其他方面实现了大致相同的目的.

Go相关问答推荐

Go程序在并发Forking 循环中停留在syscall.Wait4

macOS上GoLand 2023.3.4中的代码导航

../golang/pkg/mod/github.com/wmentor/lemmas@v0.0.6/processor.go:72:9:未定义:令牌.进程

GO:如何指定类型约束,使S方法的参数类型与接收方的参数类型相同

如何使redis池的等待超时

日志(log)文件不在 golang 的日志(log)目录中

不接受来自 stdin 的重复输入

这种合并排序的实现有什么问题?

该文件位于模块.内,该模块不包含在您的工作区中

使用golang sqlc中的引用参数

由于 main.go 文件中的本地包导入导致构建 docker 容器时出错

GoLang: gocui 边框 colored颜色

通过环境变量配置 OTLP 导出器

使用 package`regexp` 查找 Golang 中的所有 mactch 子字符串,但得到意外结果

go:识别重新定义标志的包

当有多个同名包时如何在vscode中显示golang包完整路径?

Gorm 在保存/创建时序列化 struct

Golang 泛型

GOLANG 如何使用 http.FileServer 从模板目录加载某个 html 文件

如何从字符串中删除多个换行符`\n`但只保留一个?