string在Go语言中是一个值,从而string不能为nil
1 2 3 |
x := "I am a string!" x = nil // Won't compile, strings can't be nil in Go |
然而一个string类型的指针(*string)是可以为nil值的
1 2 3 |
var x *string x = nil // Compiles! String pointers in GoLang can be nil |
根据经验来看还是使用普通的string除非你需要nil值,常规的string在Go语言中使用简单且安全,
使用指针就需要你写更多的代码去检查*string在引用前是否有值。
1 2 3 4 5 6 7 |
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 } |
string的空值””和nil是不一样的。当你在写代码的时候不思考下你需要nil的原因,你可能得不到你想要的结果。
当我使用一个指向字符串的指针时?
当你需要使用*string时,比如你需要使用*string解析json或者yaml之类的东西给structure。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
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
和 HostName2个字段的保存值是空的。这对Version字段来说可能是正常的行为,但是对于HostName就不一定了。
这个问题的答案取决于你的程序,是否能够接受丢失属性unmarshall为空字符串,如果能够接受那没问题,换句话说,如果你解析的丢失的json和空json的性能一样的话,你就可以使用正常的string。
如果””可以为Hostname的值,但是不能接受属性的丢失!
那么解决这个问题只能使用*string
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
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: '' } |
原文链接:https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html
有疑问加站长微信联系(非本文作者)