x := "I am a string!"x = nil // Won't compile, strings can't be nil in Go
var x *stringx = nil // Compiles! String pointers in GoLang can be nil
从上面的例子,我们可以看出:
- 除非你需要使用nil, 否则最好使用正常的字符串
 - 正常的字符串类型在golang中的使用,更简单更安全
 
使用指针需要我们在解引用之前做一些判断,空字符串“”和nil并不是同一个东西:
func UseString(s *string) error {if s == nil {temp := "" // *string cannot be initializeds = &temp // in one statement}value := *s // safe to dereference the *string}
结构体中使用字符串
例子1
package mainimport ("encoding/json""fmt")type Config struct {Environment stringVersion stringHostName string}func (c *Config) String() string {return fmt.Sprintf("Environment: '%v'\nVersion:'%v'\nHostName: '%v'",c.Environment, c.Version, c.HostName)}func main() {jsonDoc :=`{"Environment" : "Dev","Version" : ""}`conf := &Config{}json.Unmarshal([]byte(jsonDoc), conf)fmt.Println(conf) // Prints// Environment: 'Dev'// Version:''// HostName: ''}
我们可以看到Version和HostName都是空字符串“”, 而且我们也可以看到,即使没有对HostName做赋值,也可以得到其默认值。问题就来了,假如说,我们规定必须要为HostName赋值,这时候就需要使用字符串指针了。
例子2
package mainimport ("encoding/json""fmt")type ConfigWithPointers struct {Environment *string // pointer to stringVersion *stringHostName *string}func (c *ConfigWithPointers) String() string {var envOut, verOut, hostOut stringenvOut = "<nil>"verOut = "<nil>"hostOut = "<nil>"if c.Environment != nil { // Check for nil!envOut = *c.Environment}if c.Version != nil {verOut = *c.Version}if c.HostName != nil {hostOut = *c.HostName}return fmt.Sprintf("Environment: '%v'\nVersion:'%v'\nHostName: '%v'",envOut, verOut, hostOut)}func main() {jsonDoc :=`{"environment" : "asdf","hostName" : ""}`conf := &ConfigWithPointers{}json.Unmarshal([]byte(jsonDoc), conf)fmt.Println(conf) // Prints the following:// Environment: 'asdf'// Version:'<nil>'// HostName: ''}
