我已经习惯了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的参数的最佳方法是什么?
答案 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.NullString
和 sql.NullInt64
之类的类型允许您测试是否已为您提供了值或未使用其 .Valid
字段。
答案 4 :(得分:-3)
松开Java-think并传递f(“”)。然后使用len()进行测试:
func f(str string){ 如果len(str)> 0 { ... } else { ... } }
字符串是空的并且具有nil case的语义含义,或者有一些要处理的字符串数据。看不出那个问题。