x := "I am a string!"
x = nil // Won't compile, strings can't be nil in Go
var x *string
x = nil // Compiles! String pointers in GoLang can be nil
从上面的例子,我们可以看出:
- 除非你需要使用nil, 否则最好使用正常的字符串
- 正常的字符串类型在golang中的使用,更简单更安全
使用指针需要我们在解引用之前做一些判断,空字符串“”和nil并不是同一个东西:
func UseString(s *string) error {
if s == nil {
temp := "" // *string cannot be initialized
s = &temp // in one statement
}
value := *s // safe to dereference the *string
}
结构体中使用字符串
例子1
package main
import (
"encoding/json"
"fmt"
)
type Config struct {
Environment string
Version string
HostName 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 main
import (
"encoding/json"
"fmt"
)
type ConfigWithPointers struct {
Environment *string // pointer to string
Version *string
HostName *string
}
func (c *ConfigWithPointers) String() string {
var envOut, verOut, hostOut string
envOut = "<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: ''
}