如何优雅地将Go语言CvssV3结构体的字符串字段转为大写?
解决方案:使用反射批量处理字符串指针字段
可以利用Go的reflect包遍历结构体字段,自动识别所有*string类型的字段并将其值转为大写,无需逐个字段手动处理。
实现代码
package main import ( "fmt" "reflect" "strings" ) type CvssV3 struct { BaseScore *float32 `json:"baseScore"` AttackVector *string `json:"attackVector"` AttackComplexity *string `json:"attackComplexity"` PrivilegesRequired *string `json:"privilegesRequired"` UserInteraction *string `json:"userInteraction"` Scope *string `json:"scope"` ConfidentialityImpact *string `json:"confidentialityImpact"` IntegrityImpact *string `json:"integrityImpact"` AvailabilityImpact *string `json:"availabilityImpact"` } // UppercaseStringFields 批量将结构体中所有*string类型字段的值转为大写 func UppercaseStringFields(v interface{}) error { val := reflect.ValueOf(v) // 必须传入非空指针,否则无法修改原结构体 if val.Kind() != reflect.Ptr || val.IsNil() { return fmt.Errorf("must pass a non-nil pointer to a struct") } structVal := val.Elem() if structVal.Kind() != reflect.Struct { return fmt.Errorf("value must be a struct") } // 遍历结构体所有字段 for i := 0; i < structVal.NumField(); i++ { field := structVal.Field(i) // 检查字段是否为*string类型 if field.Kind() == reflect.Ptr && field.Type().Elem().Kind() == reflect.String { // 跳过nil指针,避免panic if field.IsNil() { continue } // 获取字符串值,转大写后重新赋值 strVal := field.Elem().String() field.Elem().SetString(strings.ToUpper(strVal)) } } return nil } func main() { baseScore := float32(4.3) attackVector := "Network" attackComplexity := "Low" privilegesRequired := "Low" userInteraction := "None" scope := "Unchanged" confidentialityImpact := "None" integrityImpact := "Low" availabilityImpact := "None" cvssV3 := CvssV3{ BaseScore: &baseScore, AttackVector: &attackVector, AttackComplexity: &attackComplexity, PrivilegesRequired: &privilegesRequired, UserInteraction: &userInteraction, Scope: &scope, ConfidentialityImpact: &confidentialityImpact, IntegrityImpact: &integrityImpact, AvailabilityImpact: &availabilityImpact, } // 调用批量转大写函数 if err := UppercaseStringFields(&cvssV3); err != nil { fmt.Printf("Error: %v\n", err) return } // 打印结果 fmt.Printf("cvssV3 = CvssV3{\n") fmt.Printf(" baseScore: %.1f,\n", *cvssV3.BaseScore) fmt.Printf(" attackVector: \"%s\",\n", *cvssV3.AttackVector) fmt.Printf(" attackComplexity: \"%s\",\n", *cvssV3.AttackComplexity) fmt.Printf(" privilegesRequired: \"%s\",\n", *cvssV3.PrivilegesRequired) fmt.Printf(" userInteraction: \"%s\",\n", *cvssV3.UserInteraction) fmt.Printf(" scope: \"%s\",\n", *cvssV3.Scope) fmt.Printf(" confidentialityImpact: \"%s\",\n", *cvssV3.ConfidentialityImpact) fmt.Printf(" integrityImpact: \"%s\",\n", *cvssV3.IntegrityImpact) fmt.Printf(" availabilityImpact: \"%s\"\n", *cvssV3.AvailabilityImpact) fmt.Printf(" }\n") }
关键说明
- 指针传递:函数要求传入结构体指针,只有指针才能修改原结构体的字段值,传值仅会修改副本。
- 类型校验:通过反射精准识别
*string类型字段,避免误处理其他类型字段。 - nil指针防护:遍历过程中跳过nil指针,防止解引用nil导致运行时panic。
- 扩展性:后续给
CvssV3新增*string类型字段时,无需修改该函数,会自动适配处理。
内容的提问来源于stack exchange,提问作者yanqin001
相关产品推荐
相关产品推荐

