A Sprintf with 3 arguments of different pointers type that can be nil. Ternary operator being unavaialble, how to avoid writing tens of lines?

huangapple go评论89阅读模式
英文:

A Sprintf with 3 arguments of different pointers type that can be nil. Ternary operator being unavaialble, how to avoid writing tens of lines?

问题

我有一个要用Sprintf创建的字符串:

message := fmt.Sprintf("Unit %s has a Level of %v, but is of Category %v",
	*entity.Name, *entity.LevelCode, *entity.CategoryCode)

entity中,这些变量是可以为nil的:

  • Name 是一个 *string 类型
  • LevelCode 是一个 *LevelCode 类型
  • CategoryCode 是一个 *CategoryCode 类型

但是如果它们有值,我想要的是这个值,而不是指针。
(例如:Unit ABC has a Level of nil, but is of Category AdministrativeUnit

在任何语言中,我会这样写:

message := fmt.Sprintf("Unit %s has a Level of %v, but is of %v Category",
	entity.Name != nil ? *entity.Name : "nil", entity.LevelCode != nil ? *entity.LevelCode : "nil", entity.CategoryCode != nil ? *entity.CategoryCode : "nil")

但是 Go 不允许三元运算符。如果我不处理nil值,Sprintf会抛出异常。

那么,我必须这样开始吗?

if entity.Name == nil && entity.LevelCode != nil && entity.CategoryCode != nil) {
   message := "Unit nil has a Level of nil, but is of nil Category"
}
else {
   if entity.Name != nil && entity.LevelCode != nil && entity.CategoryCode != nil) {
     message := fmt.Sprintf("Unit %s has a Level of nil, but is of nil Category",
	entity.Name != nil ? *entity.Name : "nil")
   }
   else {
      ...

     // 对于9种可能的nil或非nil值的组合,以及9种sprintf格式,需要编写大量的代码。
   }
}

有没有更简洁的方式来以格式化的方式输出变量的内容

<details>
<summary>英文:</summary>

I have this string to create with a `Sprintf` 

```go
message := fmt.Sprintf(&quot;Unit %s has a Level of %v, but is of Category %v&quot;,
	*entity.Name, *entity.LevelCode, *entity.CategoryCode)

In entity, the variables are pointers that can be nil:

  • Name is a *string
  • LevelCode has a *LevelCode type
  • CategoryCode has a *CategoryCode type

but if they have a value, I want this value and not the pointers.
(i.e. Unit ABC has a Level of nil, but is of Category AdministrativeUnit)

in any language, I would have wrote:

message := fmt.Sprintf(&quot;Unit %s has a Level of %v, but is of %v Category&quot;,
	entity.Name != nil ? *entity.Name : &quot;nil&quot;, entity.LevelCode != nil ? *entity.LevelCode : &quot;nil&quot;, entity.CategoryCode != nil ? *entity.CategoryCode : &quot;nil&quot;)

But Go doesn't allow ternary operator. And if I don't take care of nil values, Sprintf will throw an exception.

So, do I have to start that way?

if entity.Name == nil &amp;&amp; entity.LevelCode != nil &amp;&amp; entity.CategoryCode != nil) {
   message := &quot;Unit nil has a Level of nil, but is of nil Category&quot;
}
else {
   if entity.Name != nil &amp;&amp; entity.LevelCode != nil &amp;&amp; entity.CategoryCode != nil) {
     message := fmt.Sprintf(&quot;Unit %s has a Level of nil, but is of nil Category&quot;,
	entity.Name != nil ? *entity.Name : &quot;nil&quot;)
   }
   else {
      ...

     for 9 combinations of values nil or not nil values, and 9 sprintf formats?
   }
}

What the shortest way to dump my variables content in a formatted line?


</details>


# 答案1
**得分**: -3

谢谢有了你的帮助我成功地构建了这个函数

```go
// value函数用于处理可能为空的指针,并在它们不为空时返回它们的值。
func value[T any](v *T) string {
	if v != nil {
		return fmt.Sprintf("%v", *v)
	} else {
		return "nil"
	}
}

这样调用它:

message := fmt.Sprintf("Unit %s has a Level of %v, but is of %v Category",
    value(entity.Name), value(entity.LevelCode), value(entity.CategoryCode))

只用了一个Sprintf语句就完成了五个语句的工作... 但它能正常工作。

英文:

Thanks, with your help, I succeed in building the function.

// value treat pointers that can be nil, and return their values if they aren&#39;t.
func value[T any](v *T) string {
	if (v != nil) {
		return fmt.Sprintf(&quot;%v&quot;, *v)
	} else {
		return &quot;nil&quot;
	}
}

Called that way

message := fmt.Sprintf(&quot;Unit %s has a Level of %v, but is of %v Category&quot;,
    value(entity.Name), value(entity.LevelCode), value(entity.CategoryCode))

Five statements to write for single Sprintf... But it works.

huangapple
  • 本文由 发表于 2023年6月29日 20:26:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581055.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定