14

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

在 Go 中,字符串是原始类型,因此我不能将 nil (null) 传递给需要字符串的参数。

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

func f(s *string)

所以调用者可以调用该函数

f(nil)

或者

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

但不幸的是,以下是不允许的:

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

拥有一个接收字符串或 nil 的参数的最佳方法是什么?

4

5 回答 5

5

警告:以下是 Go1 之前的代码。也就是说,它来自预发布版本,并且不是有效的 Go 代码。

我想了更多关于如何使用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"});
于 2009-11-27T00:56:30.837 回答
1

没有真正参加回答:但是结构中的扭曲值可以提供一些通用的实用方法。(哈斯克尔也许?)

//#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);
}
于 2009-11-26T10:20:50.967 回答
1

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

于 2021-01-25T05:05:33.950 回答
1

您可以声明一个接口以将类型限制为string,并且由于接口也接受nil,因此您将涵盖这两种情况。这是您可以实现它的方式:

type (
    // An interface which accepts a string or a nil value.
    //
    // You can pass StrVal("text") or nil.
    StrOrNil interface{ isStrOrNil() }

    StrVal string // A string value for StrOrNil interface.
)

func (StrVal) isStrOrNil() {} // implement the interface

这就是你使用它的方式:

func Foo(name StrOrNil) {
    switch nameVal := name.(type) {
    case StrVal:
        fmt.Printf("String value! %s\n", string(nameVal))
    default:
        fmt.Println("Null value!")
    }
}

func main() {
    Foo(StrVal("hello world"))
    Foo(nil)
}

操场上测试它。

于 2021-10-08T16:24:18.080 回答
-4

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

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

要么字符串为空并且具有 nil 大小写的语义含义,要么有一些字符串数据要处理。看不出这有什么问题。

于 2010-01-15T06:01:21.693 回答