如何在Go中使用可为空的字符串参数的函数?

时间:2009-11-25 19:24:25

标签: string parameters go

我已经习惯了Java的String,我们可以传递null而不是“”来表示特殊含义,例如使用默认值

在Go中,string是基本类型,因此我无法将nil(null)传递给需要字符串的参数。

我可以使用指针类型编写函数,如下所示:

func f(s *string)

所以调用者可以将该函数称为

f(nil)

// not so elegant
temp := "hello";
f(&temp) 

但遗憾的是不允许以下内容:

// elegant but disallowed
f(&"hello");

使用接收字符串或nil的参数的最佳方法是什么?

5 个答案:

答案 0 :(得分:6)

我更多地考虑了如何使用struct来实现这一点。这就是我想出的:

type MyString struct {
    val string;
}

func f(s MyString) {
    if s == nil {
        s = MyString{"some default"};
    }
    //do something with s.val
}

然后你可以这样打电话给f

f(nil);
f(MyString{"not a default"});

答案 1 :(得分:3)

我知道我在这个派对上已经很晚了,但我在寻找类似问题时发现了这一点,并且认为我为后代添加了我的解决方案。

根据您的使用情况,使用variadic function可能是您的朋友。这允许您向函数输入零个或多个相同类型的参数,这些参数在函数中作为数组接收。

// My variadic function
func f(s string...) {
  if length(s) == 0 {
    // We got a NULL
    fmt.Println("default value")
  } else {
    // We got a value
    fmt.Println(s[0])
  }
}

f() // works!
f("has a value") // works!

这个解决方案确实要求你知道你在开发时会以零通过;你不能只是致电f(nil)并让它发挥作用。但是,如果这在您的特定用例中不是问题,那么它可能是一个非常优雅的解决方案,不需要您定义任何其他数据类型。

答案 2 :(得分:1)

不是真正的回答:但结构中的翘曲值可以提供一些通用的实用方法。 (Haskell Maybe?)

//#maybe.go
package maybe

import "log"

type MayHaveValue struct {
 IsValue bool;
}

func (this MayHaveValue) IsJust() bool {
 return this.IsValue
}

type AString struct {
 MayHaveValue;
 Value string;
}

func String(aString string) AString {
 return AString{MayHaveValue{true}, aString}
}

var NoString AString = AString{MayHaveValue{false}, ""}

func (this AString) String() (value string) {
 if this.IsJust() == true {
  value = this.Value;
 } else {
  log.Crash("Access to non existent maybeString value");
 }
 return;
}

func (this AString) OrDefault(defaultString string) (value string) {
 if this.IsJust() {
  value = this.Value;
 } else {
  value = defaultString;
 }
 return;
}

//#main.go
package main

import "fmt"
import "maybe"

func say(canBeString maybe.AString) {
 if canBeString.IsJust() {
  fmt.Printf("Say : %v\n", canBeString.String());
 } else {
  fmt.Print("Nothing to say !\n");
 }
}

func sayMaybeNothing (canBeString maybe.AString) {
 fmt.Printf("Say : %v\n", canBeString.OrDefault("nothing"));
}

func main() {
 aString := maybe.String("hello");
 say(aString);
 sayMaybeNothing(aString);
 noString := maybe.NoString;
 say(noString);
 sayMaybeNothing(noString);
}

答案 3 :(得分:1)

如果您需要处理可能的空值(例如,因为您正在与可能提供它们的数据库交谈),database/sql 包具有诸如 sql.NullStringsql.NullInt64 之类的类型允许您测试是否已为您提供了值或未使用其 .Valid 字段。

答案 4 :(得分:-3)

松开Java-think并传递f(“”)。然后使用len()进行测试:

func f(str string){     如果len(str)> 0 {        ...     } else {        ...     } }

字符串是空的并且具有nil case的语义含义,或者有一些要处理的字符串数据。看不出那个问题。