我对Go真的很陌生,所以需要一些建议。 我有一个结构:
type Employee struct {
Name string
Designation string
Department string
Salary int
Email string
}
我想将字符串字段连接成一种员工描述。 因此,我可以说: toString(employee)并获得:
John Smith Manager Sales john.smith@example.com
我试图获取每个字段,检查它们是否为空并将它们切成薄片并在最后加入它们
employeeDescArr := make([]string, 0, 4)
if strings.TrimSpace(value) != "" {
append(employee.GetName(), value)
}...
return strings.Join(employeeDescArr[:], " ")
我认为这种方法非常冗长,显示出缺乏围棋技巧。 改用字符串生成器更好吗? 有没有一种方法可以以反射的方式遍历结构的所有字段并加入它们?
答案 0 :(得分:1)
遍历字符串字段并收集非空字符串。加入领域。
func (e *Employee) String() string {
var parts []string
for _, s := range []string{e.Name, e.Designation, e.Department, e.Email} {
if strings.TrimSpace(s) != "" {
parts = append(parts, s)
}
}
return strings.Join(parts, " ")
}
因为strings.Join函数是使用strings.Builder实现的,所以替换字符串没有任何好处。使用使用strings.Builder的应用程序代码进行联接。
以下是使用反射来避免在字符串函数中列出字段的方法:
var stringType = reflect.TypeOf("")
func (e *Employee) String() string {
v := reflect.ValueOf(e).Elem()
var parts []string
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Type() == stringType {
s := f.String()
if strings.TrimSpace(s) != "" {
parts = append(parts, s)
}
}
}
return strings.Join(parts, " ")
}
如果要包括所有字段(包括非字符串和空字符串),则可以fmt.Sprint(e)
来获取字符串。参见https://play.golang.org/p/yntZxQ-Xs6C。
答案 1 :(得分:0)
您可以通过编写实用程序功能以使附加项带有“非空白字符串”检查来使它变得不那么冗长。
此外,您可以使类型实现实现String()
方法,该方法的优点是可以在fmt
打印功能中使用时按需要打印。
此addToString
函数是通用的,因此如果对其他类型执行此操作,则可以重用它:
func addToString(original string, addition interface{}) string {
additionStr := fmt.Sprint(addition)
if additionStr != "" {
if original != "" {
original += " "
}
original += additionStr
}
return original
}
然后您可以像这样实现它,它并不那么冗长:
type Employee struct {
Name string
Designation string
Department string
Salary int
Email string
}
func (e *Employee) String() string {
theString := ""
theString = addToString(theString, e.Name)
theString = addToString(theString, e.Designation)
theString = addToString(theString, e.Department)
theString = addToString(theString, e.Salary)
theString = addToString(theString, e.Email)
return theString
}
并像这样使用它:
func main() {
emp := &Employee{
Name: "Jonh",
Department: "Some dept",
}
fmt.Println(emp.String())
fmt.Println(emp)
}
哪个会输出:
Jonh Some dept 0
Jonh Some dept 0
答案 2 :(得分:0)
我认为您想改用Stringer接口。即:
package main
import (
"fmt"
"strings"
"strconv"
)
type Employee struct {
Name string
Designation string
Department string
Salary int
Email string
}
func main() {
emp1:=Employee{Name:"Cetin", Department:"MS", Salary:50}
emp2:=Employee{Name:"David", Designation:"Designation", Email:"david@nowhere.com"}
emp3:=Employee{Department:"Space", Salary:10}
fmt.Println(emp1)
fmt.Println(emp2)
fmt.Println(emp3)
}
func (e Employee) String() string {
var salary string
if e.Salary > 0 {
salary = strconv.Itoa(e.Salary) + " "
} else {
salary = ""
}
return strings.TrimSpace(
strings.TrimSpace(
strings.TrimSpace(e.Name + " " + e.Designation) + " " +
e.Department) + " " +
salary +
e.Email)
}
游乐场:https://play.golang.org/p/L8ft7SeXpqt
PS:我后来发现您只希望使用字符串字段,但无论如何都没有删除薪水。
答案 3 :(得分:0)
import "fmt"
Stringer由具有String方法的任何值实现, 定义该值的“本机”格式。使用String方法 打印作为操作数传递的值,使其接受任何格式 字符串或未格式化的打印机(例如“打印”)。
type Stringer interface { String() string }
为类型String
写一个Employee
方法。
例如,
package main
import (
"fmt"
"strings"
)
type Employee struct {
Name string
Designation string
Department string
Salary int
Email string
}
func appendItem(items *strings.Builder, item string) {
if len(item) > 0 {
if items.Len() > 0 {
items.WriteByte(' ')
}
items.WriteString(item)
}
}
func (e Employee) String() string {
s := new(strings.Builder)
appendItem(s, e.Name)
appendItem(s, e.Designation)
appendItem(s, e.Department)
appendItem(s, e.Email)
return s.String()
}
func main() {
ee := Employee{
Name: "John Smith",
Designation: "Manager",
Department: "Sales",
Email: "john.smith@example.com",
Salary: 42000,
}
fmt.Println(ee)
}
游乐场:https://play.golang.org/p/EPBjgi8usJ-
输出:
John Smith Manager Sales john.smith@example.com
我想将字符串字段连接成一种雇员 说明。
是否有一种方法可以遍历一个结构体的所有字段 反思方式并加入他们?
[反射是]功能强大的工具,应谨慎使用,除非绝对必要,否则应避免使用。罗伯·派克
The Go Blog: The Laws of Reflection
反射永远不清楚。罗伯·派克
Go Proverbs - Rob Pike - Gopherfest - November 18, 2015
Go编译后的代码非常有效。 Go反射包功能在运行时进行解释。
遍历结构的所有字段与SQL中的SELECT * FROM table;
具有相同的错误。返回的值是在运行时而不是编译时确定的。
如果是您的情况,业务要求是隐藏机密字段(例如薪水),并将显示的字段限制为几个关键的描述性字段。不可避免地,字段将被添加到结构中。 “连接字符串字段”规范现在或将来都不太可能正确。