4 回答
TA贡献1810条经验 获得超4个赞
循环遍历字符串字段并收集非空字符串。加入田野。
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.Join 替换为使用 strings.Builder 的应用程序代码没有任何好处。
以下是如何使用 Reflect 来避免列出字符串函数中的字段:
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)获取一个字符串。
TA贡献1804条经验 获得超7个赞
我认为您会想使用 Stringer 接口。IE:
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:我后来注意到你只想要字符串字段,但无论如何都没有删除工资。
TA贡献1795条经验 获得超7个赞
您可以通过编写一个实用函数来通过“非空白字符串”检查进行添加来使其不那么冗长。
另外,您可以让您的类型实现一个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
TA贡献1824条经验 获得超8个赞
封装 fmt
import "fmt"类型纵梁
Stringer 由具有 String 方法的任何值实现,该方法定义该值的“本机”格式。String 方法用于将作为操作数传递的值打印到任何接受字符串的格式或打印到未格式化的打印机(例如 Print)。
type Stringer interface { String() string}
String
为 type编写一个方法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
我想将字符串字段连接成一种员工描述。
有没有一种方法可以以反射方式迭代结构体的所有字段并将它们连接起来?
迭代结构体的所有字段具有与SELECT * FROM table;
SQL 中相同的错误。返回的值是在运行时而不是编译时确定的。
如果您的情况,业务要求是隐藏机密字段,例如工资,并将显示的字段限制为几个关键的描述性字段。不可避免地,字段将被添加到结构中。“连接字符串字段”规范现在或将来不太可能是正确的。
- 4 回答
- 0 关注
- 174 浏览
添加回答
举报