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:"[email protected]"}
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:? ? ? ?"[email protected]",
? ? ? ? Salary:? ? ? 42000,
? ? }
? ? fmt.Println(ee)
}
游樂場:https://play.golang.org/p/EPBjgi8usJ-
輸出:
[email protected]
我想將字符串字段連接成一種員工描述。
有沒有一種方法可以以反射方式迭代結構體的所有字段并將它們連接起來?
迭代結構體的所有字段具有與SELECT * ?FROM table;
SQL 中相同的錯誤。返回的值是在運行時而不是編譯時確定的。
如果您的情況,業務要求是隱藏機密字段,例如工資,并將顯示的字段限制為幾個關鍵的描述性字段。不可避免地,字段將被添加到結構中?!斑B接字符串字段”規范現在或將來不太可能是正確的。
- 4 回答
- 0 關注
- 243 瀏覽
添加回答
舉報