reflect.Value.CanSet()falseSet()
package main 

import (
    "fmt" 
    "reflect" 
) 

type Person struct { 
    FirstName *string 
    LastName *string 
} 

func main() { 
    p := Person{} 
    firstName := "Ryan" 
    p.FirstName = &firstName 

    rp := reflect.ValueOf(p) 
    fmt.Println("rp:", rp) 

    for i := 0; i < rp.NumField(); i++ { 
     fmt.Printf("%s: Pointer: %d CanSet: %t\n", rp.Type().Field(i).Name, rp.Field(i).Pointer(), rp.Field(i).Elem().CanSet()) 
    } 

    rp.Field(0).Elem().SetString("Brian") 
    fmt.Println(*p.FirstName) 

    // Yields nil pointer error 
    // rp.Field(1).Elem().SetString("Johnson") 
    // fmt.Println(*p.LastName) 

    fmt.Println(rp.Field(1).Type()) 
    fmt.Println(rp.Field(1).CanSet()) 
    // fmt.Println(rp.Field(1).Elem().Type()) // nil pointer here also 
    fmt.Println(rp.Field(1).Elem().CanSet()) 
} 

2017-05-02 Ryan Smith

+0

我会在这里问一个显而易见的问题。 .. 你为什么想做这个?我自己从来没有见过使用指向字符串指针的很多理由,也没有看到它们在标准库中使用。 –

+1

公平的问题。当我公开一个REST API时,我知道客户端是否提供了一个字段。如果它们不是指针,则字符串的空值是''“'。然后,我不得不问,客户是否提供''“'或者他们没有提供什么?另外,我在结构字段中添加了独特的标签,如''Validate'和'Transform'。所以,我使用反射包来解析这些。 –