diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index a68baaf8fc8..a062493eadf 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -4,7 +4,7 @@ # If a copy of the MIT was not distributed with this file, # You can obtain one at https://github.com/gogf/gf. -name: GolangCI Lint +name: golangci-lint on: push: branches: diff --git a/.golangci.yml b/.golangci.yml index a6eac8e4986..704df968536 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,7 +1,7 @@ version: "2" run: concurrency: 4 - go: "1.23" + go: "1.25" modules-download-mode: readonly issues-exit-code: 2 tests: false @@ -188,7 +188,7 @@ formatters: - blank - default - dot - - prefix(github.com/gogf/gf) + - prefix(github.com/gogf/gf/v2) - prefix(github.com/gogf/gf/cmd) - prefix(github.com/gogf/gfcontrib) - prefix(github.com/gogf/gf/example) diff --git a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go index 55c30d1bb58..1ed9853e5d5 100644 --- a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go +++ b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_issue_test.go @@ -378,7 +378,7 @@ func Test_Gen_Dao_Issue3459(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { //_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i])) t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } @@ -450,7 +450,7 @@ func Test_Gen_Dao_Issue3749(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { //_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i])) t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } diff --git a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go index 8d20fe8c169..bbe18735dbb 100644 --- a/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go +++ b/cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go @@ -107,7 +107,7 @@ func Test_Gen_Dao_Default(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } }) @@ -208,7 +208,7 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { //_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i])) t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } @@ -311,7 +311,7 @@ func Test_Gen_Dao_FieldMapping(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { //_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i])) t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } @@ -403,7 +403,7 @@ func Test_Gen_Dao_Sqlite3(t *testing.T) { filepath.FromSlash(testPath + "/model/do/table_user.go"), filepath.FromSlash(testPath + "/model/entity/table_user.go"), } - for i, _ := range files { + for i := range files { //_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i])) t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i])) } diff --git a/cmd/gf/internal/cmd/genctrl/genctrl.go b/cmd/gf/internal/cmd/genctrl/genctrl.go index 87d87766ee2..71771f593d8 100644 --- a/cmd/gf/internal/cmd/genctrl/genctrl.go +++ b/cmd/gf/internal/cmd/genctrl/genctrl.go @@ -9,13 +9,14 @@ package genctrl import ( "context" - "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" "github.com/gogf/gf/v2/container/gset" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gtag" + + "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" ) const ( diff --git a/cmd/gf/internal/cmd/genservice/genservice.go b/cmd/gf/internal/cmd/genservice/genservice.go index 568782a6cdf..a68c3e3be1a 100644 --- a/cmd/gf/internal/cmd/genservice/genservice.go +++ b/cmd/gf/internal/cmd/genservice/genservice.go @@ -13,8 +13,6 @@ import ( "sync" "sync/atomic" - "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" - "github.com/gogf/gf/cmd/gf/v2/internal/utility/utils" "github.com/gogf/gf/v2/container/garray" "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/container/gset" @@ -25,6 +23,9 @@ import ( "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gtag" + + "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" + "github.com/gogf/gf/cmd/gf/v2/internal/utility/utils" ) const ( diff --git a/cmd/gf/internal/utility/utils/utils.go b/cmd/gf/internal/utility/utils/utils.go index 94047db1902..9e324863da2 100644 --- a/cmd/gf/internal/utility/utils/utils.go +++ b/cmd/gf/internal/utility/utils/utils.go @@ -12,12 +12,13 @@ import ( "golang.org/x/tools/imports" - "github.com/gogf/gf/cmd/gf/v2/internal/consts" - "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/gproc" "github.com/gogf/gf/v2/text/gregex" "github.com/gogf/gf/v2/text/gstr" + + "github.com/gogf/gf/cmd/gf/v2/internal/consts" + "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" ) // GoFmt formats the source file and adds or removes import statements as necessary. diff --git a/container/garray/garray_sorted_any.go b/container/garray/garray_sorted_any.go index d2f0a0a7241..3644933aebf 100644 --- a/container/garray/garray_sorted_any.go +++ b/container/garray/garray_sorted_any.go @@ -498,13 +498,9 @@ func (a *SortedArray) Unique() *SortedArray { if len(a.array) == 0 { return a } - i := 0 - for { - if i == len(a.array)-1 { - break - } + for i := 0; i < len(a.array)-1; { if a.getComparator()(a.array[i], a.array[i+1]) == 0 { - a.array = append(a.array[:i+1], a.array[i+1+1:]...) + a.array = append(a.array[:i+1], a.array[i+2:]...) } else { i++ } diff --git a/container/garray/garray_sorted_int.go b/container/garray/garray_sorted_int.go index 6fdc67f110d..48d8469b173 100644 --- a/container/garray/garray_sorted_int.go +++ b/container/garray/garray_sorted_int.go @@ -496,13 +496,9 @@ func (a *SortedIntArray) Unique() *SortedIntArray { if len(a.array) == 0 { return a } - i := 0 - for { - if i == len(a.array)-1 { - break - } + for i := 0; i < len(a.array)-1; { if a.getComparator()(a.array[i], a.array[i+1]) == 0 { - a.array = append(a.array[:i+1], a.array[i+1+1:]...) + a.array = append(a.array[:i+1], a.array[i+2:]...) } else { i++ } diff --git a/container/garray/garray_sorted_str.go b/container/garray/garray_sorted_str.go index 8a4973d0b17..6a50ae24ce3 100644 --- a/container/garray/garray_sorted_str.go +++ b/container/garray/garray_sorted_str.go @@ -498,13 +498,9 @@ func (a *SortedStrArray) Unique() *SortedStrArray { if len(a.array) == 0 { return a } - i := 0 - for { - if i == len(a.array)-1 { - break - } + for i := 0; i < len(a.array)-1; { if a.getComparator()(a.array[i], a.array[i+1]) == 0 { - a.array = append(a.array[:i+1], a.array[i+1+1:]...) + a.array = append(a.array[:i+1], a.array[i+2:]...) } else { i++ } diff --git a/container/gmap/gmap_list_map.go b/container/gmap/gmap_list_map.go index cfb3791d835..2b426176fcf 100644 --- a/container/gmap/gmap_list_map.go +++ b/container/gmap/gmap_list_map.go @@ -545,7 +545,7 @@ func (m ListMap) MarshalJSON() (jsonBytes []byte, err error) { if buffer.Len() > 1 { buffer.WriteByte(',') } - buffer.WriteString(fmt.Sprintf(`"%v":%s`, key, valueBytes)) + fmt.Fprintf(buffer, `"%v":%s`, key, valueBytes) return true }) buffer.WriteByte('}') diff --git a/container/gpool/gpool.go b/container/gpool/gpool.go index bd432c9e396..f6b5845480b 100644 --- a/container/gpool/gpool.go +++ b/container/gpool/gpool.go @@ -166,10 +166,7 @@ func (p *Pool) checkExpireItems(ctx context.Context) { // by comparing with this timestamp. It is not accurate comparison for // every item expired, but high performance. var timestampMilli = gtime.TimestampMilli() - for { - if latestExpire > timestampMilli { - break - } + for latestExpire <= timestampMilli { if r := p.list.PopFront(); r != nil { item := r.(*poolItem) latestExpire = item.expireAt diff --git a/contrib/drivers/mysql/mysql_z_unit_issue_test.go b/contrib/drivers/mysql/mysql_z_unit_issue_test.go index a4ce33e7abc..6f4656bec6e 100644 --- a/contrib/drivers/mysql/mysql_z_unit_issue_test.go +++ b/contrib/drivers/mysql/mysql_z_unit_issue_test.go @@ -1508,7 +1508,7 @@ func Test_Issue3968(t *testing.T) { return nil, err } if result != nil { - for i, _ := range result { + for i := range result { result[i]["location"] = gvar.New("ny") } } diff --git a/database/gdb/gdb_func.go b/database/gdb/gdb_func.go index 3bc40f590a8..ba141860949 100644 --- a/database/gdb/gdb_func.go +++ b/database/gdb/gdb_func.go @@ -598,11 +598,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n // Regular string and parameter place holder handling. // Eg: // Where("id in(?) and name=?", g.Slice{1,2,3}, "john") - i := 0 - for { - if i >= len(in.Args) { - break - } + for i := 0; i < len(in.Args); i++ { // =============================================================== // Sub query, which is always used along with a string condition. // =============================================================== @@ -621,7 +617,6 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n in.Args = gutil.SliceDelete(in.Args, i) continue } - i++ } buffer.WriteString(whereStr) } @@ -858,18 +853,18 @@ func handleSliceAndStructArgsForSql( // Special struct handling. case reflect.Struct: - switch oldArg.(type) { + switch v := oldArg.(type) { // The underlying driver supports time.Time/*time.Time types. case time.Time, *time.Time: newArgs = append(newArgs, oldArg) continue case gtime.Time: - newArgs = append(newArgs, oldArg.(gtime.Time).Time) + newArgs = append(newArgs, v.Time) continue case *gtime.Time: - newArgs = append(newArgs, oldArg.(*gtime.Time).Time) + newArgs = append(newArgs, v.Time) continue default: diff --git a/database/gdb/gdb_type_result_scanlist.go b/database/gdb/gdb_type_result_scanlist.go index bea9aa76b7c..0017c090b2f 100644 --- a/database/gdb/gdb_type_result_scanlist.go +++ b/database/gdb/gdb_type_result_scanlist.go @@ -185,7 +185,7 @@ func checkGetSliceElementInfoForScanList(structSlicePointer any, bindToAttrName } if reflectKind == reflect.Slice || reflectKind == reflect.Array { reflectType = reflectType.Elem() - reflectKind = reflectType.Kind() + // reflectKind = reflectType.Kind() } out.BindToAttrType = reflectType return @@ -342,7 +342,7 @@ func doScanList(in doScanListInput) (err error) { arrayElemValue = reflect.New(arrayItemType.Elem()).Elem() arrayValue.Index(i).Set(arrayElemValue.Addr()) } - } else { + // } else { // Like: []Entity } bindToAttrValue = arrayElemValue.FieldByName(in.BindToAttrName) diff --git a/database/gredis/gredis_redis.go b/database/gredis/gredis_redis.go index 3c797771585..f7f1a0dd57d 100644 --- a/database/gredis/gredis_redis.go +++ b/database/gredis/gredis_redis.go @@ -52,14 +52,14 @@ const errorNilAdapter = `redis adapter is not set, missing configuration or adap // initGroup initializes the group object of redis. func (r *Redis) initGroup() *Redis { r.localGroup = localGroup{ - localGroupGeneric: r.localAdapter.GroupGeneric(), - localGroupHash: r.localAdapter.GroupHash(), - localGroupList: r.localAdapter.GroupList(), - localGroupPubSub: r.localAdapter.GroupPubSub(), - localGroupScript: r.localAdapter.GroupScript(), - localGroupSet: r.localAdapter.GroupSet(), - localGroupSortedSet: r.localAdapter.GroupSortedSet(), - localGroupString: r.localAdapter.GroupString(), + localGroupGeneric: r.GroupGeneric(), + localGroupHash: r.GroupHash(), + localGroupList: r.GroupList(), + localGroupPubSub: r.GroupPubSub(), + localGroupScript: r.GroupScript(), + localGroupSet: r.GroupSet(), + localGroupSortedSet: r.GroupSortedSet(), + localGroupString: r.GroupString(), } return r } diff --git a/debug/gdebug/gdebug_stack.go b/debug/gdebug/gdebug_stack.go index 20db7d802db..925f3392252 100644 --- a/debug/gdebug/gdebug_stack.go +++ b/debug/gdebug/gdebug_stack.go @@ -67,7 +67,7 @@ func StackWithFilters(filters []string, skip ...int) string { if index > 9 { space = " " } - buffer.WriteString(fmt.Sprintf("%d.%s%s\n %s:%d\n", index, space, name, file, line)) + fmt.Fprintf(buffer, "%d.%s%s\n %s:%d\n", index, space, name, file, line) index++ } else { break diff --git a/encoding/gcompress/gcompress_zlib.go b/encoding/gcompress/gcompress_zlib.go index c45b3d2bd5c..aa962ceddb0 100644 --- a/encoding/gcompress/gcompress_zlib.go +++ b/encoding/gcompress/gcompress_zlib.go @@ -17,7 +17,7 @@ import ( // Zlib compresses `data` with zlib algorithm. func Zlib(data []byte) ([]byte, error) { - if data == nil || len(data) < 13 { + if len(data) < 13 { return data, nil } var ( @@ -39,7 +39,7 @@ func Zlib(data []byte) ([]byte, error) { // UnZlib decompresses `data` with zlib algorithm. func UnZlib(data []byte) ([]byte, error) { - if data == nil || len(data) < 13 { + if len(data) < 13 { return data, nil } var ( diff --git a/encoding/gini/gini.go b/encoding/gini/gini.go index 90e88015898..7b3b37b55e9 100644 --- a/encoding/gini/gini.go +++ b/encoding/gini/gini.go @@ -89,12 +89,12 @@ func Encode(data map[string]any) (res []byte, err error) { for section, item := range data { // Section key-value pairs. if m, ok = item.(map[string]any); ok { - n, err = w.WriteString(fmt.Sprintf("[%s]\n", section)) + n, err = fmt.Fprintf(w, "[%s]\n", section) if err != nil || n == 0 { return nil, gerror.Wrapf(err, "w.WriteString failed") } for k, v := range m { - if n, err = w.WriteString(fmt.Sprintf("%s=%v\n", k, v)); err != nil || n == 0 { + if n, err = fmt.Fprintf(w, "%s=%v\n", k, v); err != nil || n == 0 { return nil, gerror.Wrapf(err, "w.WriteString failed") } } @@ -102,7 +102,7 @@ func Encode(data map[string]any) (res []byte, err error) { } // Simple key-value pairs. for k, v := range data { - if n, err = w.WriteString(fmt.Sprintf("%s=%v\n", k, v)); err != nil || n == 0 { + if n, err = fmt.Fprintf(w, "%s=%v\n", k, v); err != nil || n == 0 { return nil, gerror.Wrapf(err, "w.WriteString failed") } } diff --git a/errors/gerror/gerror_error_stack.go b/errors/gerror/gerror_error_stack.go index 553abd5a8bf..3bbec7f6eb2 100644 --- a/errors/gerror/gerror_error_stack.go +++ b/errors/gerror/gerror_error_stack.go @@ -103,7 +103,7 @@ func filterLinesOfStackInfos(infos []*stackInfo) { func formatStackInfos(infos []*stackInfo) string { buffer := bytes.NewBuffer(nil) for i, info := range infos { - buffer.WriteString(fmt.Sprintf("%d. %s\n", i+1, info.Message)) + fmt.Fprintf(buffer, "%d. %s\n", i+1, info.Message) if info.Lines != nil && info.Lines.Len() > 0 { formatStackLines(buffer, info.Lines) } @@ -124,10 +124,11 @@ func formatStackLines(buffer *bytes.Buffer, lines *list.List) string { if i >= 9 { space = " " } - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + buffer, " %d).%s%s\n %s\n", i+1, space, line.Function, line.FileLine, - )) + ) } return buffer.String() } diff --git a/net/ghttp/ghttp_middleware_handler_response.go b/net/ghttp/ghttp_middleware_handler_response.go index 87ffb9dc5bf..17c9f91eab3 100644 --- a/net/ghttp/ghttp_middleware_handler_response.go +++ b/net/ghttp/ghttp_middleware_handler_response.go @@ -37,7 +37,7 @@ func MiddlewareHandlerResponse(r *Request) { r.Middleware.Next() // There's custom buffer content, it then exits current handler. - if r.Response.BufferLength() > 0 || r.Response.Writer.BytesWritten() > 0 { + if r.Response.BufferLength() > 0 || r.Response.BytesWritten() > 0 { return } diff --git a/net/ghttp/ghttp_server_router_serve.go b/net/ghttp/ghttp_server_router_serve.go index 548a1096528..b5c03fe25b0 100644 --- a/net/ghttp/ghttp_server_router_serve.go +++ b/net/ghttp/ghttp_server_router_serve.go @@ -63,7 +63,7 @@ func (s *Server) getHandlersWithCache(r *Request) (parsedItems []*HandlerItemPar // Special http method OPTIONS handling. // It searches the handler with the request method instead of OPTIONS method. if method == http.MethodOptions { - if v := r.Request.Header.Get("Access-Control-Request-Method"); v != "" { + if v := r.Header.Get("Access-Control-Request-Method"); v != "" { method = v } } diff --git a/net/ghttp/ghttp_z_unit_feature_router_standard_test.go b/net/ghttp/ghttp_z_unit_feature_router_standard_test.go index 286bfb15d71..8c62155abf2 100644 --- a/net/ghttp/ghttp_z_unit_feature_router_standard_test.go +++ b/net/ghttp/ghttp_z_unit_feature_router_standard_test.go @@ -326,7 +326,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) { }) s.BindHandler("/test1_slice", func(ctx context.Context, req *TestReq) (res []Test1Res, err error) { return []Test1Res{ - Test1Res{ + { Age: TestGeneric[int]{ Test: req.Age, }, @@ -341,7 +341,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) { s.BindHandler("/test2_slice", func(ctx context.Context, req *TestReq) (res []Test2Res, err error) { return []Test2Res{ - Test2Res{ + { Test: req.Age, }, }, nil @@ -359,7 +359,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) { s.BindHandler("/test3_slice", func(ctx context.Context, req *TestReq) (res []TestGenericRes[int], err error) { return []TestGenericRes[int]{ - TestGenericRes[int]{ + { Test: req.Age, }, }, nil diff --git a/net/gipv4/gipv4_ip.go b/net/gipv4/gipv4_ip.go index 7dda6b9265b..60da1e8b4a5 100644 --- a/net/gipv4/gipv4_ip.go +++ b/net/gipv4/gipv4_ip.go @@ -24,7 +24,7 @@ func GetIpArray() (ips []string, err error) { } for _, address := range interfaceAddr { ipNet, isValidIpNet := address.(*net.IPNet) - if !(isValidIpNet && !ipNet.IP.IsLoopback()) { + if !isValidIpNet || ipNet.IP.IsLoopback() { continue } if ipNet.IP.To4() != nil { diff --git a/net/goai/goai_path.go b/net/goai/goai_path.go index 0074ae457fb..516def48707 100644 --- a/net/goai/goai_path.go +++ b/net/goai/goai_path.go @@ -85,7 +85,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error { } var ( - mime string + // mime string path = Path{XExtensions: make(XExtensions)} inputMetaMap = gmeta.Data(inputObject.Interface()) outputMetaMap = gmeta.Data(outputObject.Interface()) @@ -152,9 +152,9 @@ func (oai *OpenApiV3) addPath(in addPathInput) error { return err } // Allowed request mime. - if mime = inputMetaMap[gtag.Mime]; mime == "" { - mime = inputMetaMap[gtag.Consumes] - } + // if mime = inputMetaMap[gtag.Mime]; mime == "" { + // mime = inputMetaMap[gtag.Consumes] + // } } // path security diff --git a/os/gcache/gcache_adapter_memory.go b/os/gcache/gcache_adapter_memory.go index 2f80a019a61..a205c522057 100644 --- a/os/gcache/gcache_adapter_memory.go +++ b/os/gcache/gcache_adapter_memory.go @@ -472,7 +472,6 @@ func (c *AdapterMemory) handleLruKey(ctx context.Context, keys ...any) { _, _ = c.doRemove(ctx, evictedKeys...) return } - return } // clearByKey deletes the key-value pair with given `key`. diff --git a/os/gcfg/gcfg_adapter_file_path.go b/os/gcfg/gcfg_adapter_file_path.go index f799e51d260..0044072eff2 100644 --- a/os/gcfg/gcfg_adapter_file_path.go +++ b/os/gcfg/gcfg_adapter_file_path.go @@ -56,20 +56,20 @@ func (a *AdapterFile) SetPath(directoryPath string) (err error) { if realPath == "" { buffer := bytes.NewBuffer(nil) if a.searchPaths.Len() > 0 { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `SetPath failed: cannot find directory "%s" in following paths:`, directoryPath, - )) + ) a.searchPaths.RLockFunc(func(array []string) { for k, v := range array { - buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v)) + fmt.Fprintf(buffer, "\n%d. %s", k+1, v) } }) } else { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `SetPath failed: path "%s" does not exist`, directoryPath, - )) + ) } return gerror.New(buffer.String()) } @@ -136,20 +136,18 @@ func (a *AdapterFile) doAddPath(directoryPath string) (err error) { if realPath == "" { buffer := bytes.NewBuffer(nil) if a.searchPaths.Len() > 0 { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `AddPath failed: cannot find directory "%s" in following paths:`, - directoryPath, - )) + directoryPath) a.searchPaths.RLockFunc(func(array []string) { for k, v := range array { - buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v)) + fmt.Fprintf(buffer, "\n%d. %s", k+1, v) } }) } else { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `AddPath failed: path "%s" does not exist`, - directoryPath, - )) + directoryPath) } return gerror.New(buffer.String()) } @@ -269,34 +267,30 @@ func (a *AdapterFile) GetFilePath(fileNameOrPath ...string) (filePath string, er var buffer = bytes.NewBuffer(nil) if a.searchPaths.Len() > 0 { if !gstr.InArray(supportedFileTypes, fileExtName) { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `possible config files "%s" or "%s" not found in resource manager or following system searching paths:`, - usedFileNameOrPath, fmt.Sprintf(`%s.%s`, usedFileNameOrPath, gstr.Join(supportedFileTypes, "/")), - )) + usedFileNameOrPath, fmt.Sprintf(`%s.%s`, usedFileNameOrPath, gstr.Join(supportedFileTypes, "/"))) } else { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `specified config file "%s" not found in resource manager or following system searching paths:`, - usedFileNameOrPath, - )) + usedFileNameOrPath) } a.searchPaths.RLockFunc(func(array []string) { index := 1 for _, searchPath := range array { searchPath = gstr.TrimRight(searchPath, `\/`) for _, tryFolder := range localSystemTryFolders { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, "\n%d. %s", - index, gfile.Join(searchPath, tryFolder), - )) + index, gfile.Join(searchPath, tryFolder)) index++ } } }) } else { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, `cannot find config file "%s" with no filePath configured`, - usedFileNameOrPath, - )) + usedFileNameOrPath) } err = gerror.NewCode(gcode.CodeNotFound, buffer.String()) } diff --git a/os/gcmd/gcmd_command_run.go b/os/gcmd/gcmd_command_run.go index c8de329603d..694af4da9b4 100644 --- a/os/gcmd/gcmd_command_run.go +++ b/os/gcmd/gcmd_command_run.go @@ -46,14 +46,14 @@ func (c *Command) RunWithValue(ctx context.Context) (value any) { buffer = bytes.NewBuffer(nil) ) if code.Code() == gcode.CodeNotFound.Code() { - buffer.WriteString(fmt.Sprintf("ERROR: %s\n", gstr.Trim(err.Error()))) + fmt.Fprintf(buffer, "ERROR: %s\n", gstr.Trim(err.Error())) if lastCmd, ok := detail.(*Command); ok { lastCmd.PrintTo(buffer) } else { c.PrintTo(buffer) } } else { - buffer.WriteString(fmt.Sprintf("%+v\n", err)) + fmt.Fprintf(buffer, "%+v\n", err) } if gtrace.GetTraceID(ctx) == "" { fmt.Println(buffer.String()) diff --git a/os/gcron/gcron_schedule_fix.go b/os/gcron/gcron_schedule_fix.go index b5e10dbc804..11461893569 100644 --- a/os/gcron/gcron_schedule_fix.go +++ b/os/gcron/gcron_schedule_fix.go @@ -19,30 +19,26 @@ func (s *cronSchedule) getAndUpdateLastCheckTimestamp(ctx context.Context, t tim currentTimestamp = t.Unix() lastCheckTimestamp = s.lastCheckTimestamp.Val() ) - switch { + switch lastCheckTimestamp { // Often happens, timer triggers in the same second, but the millisecond is different. // Example: // lastCheckTimestamp: 2024-03-26 19:47:34.000 // currentTimestamp: 2024-03-26 19:47:34.999 - case - lastCheckTimestamp == currentTimestamp: + case currentTimestamp: lastCheckTimestamp += 1 // Often happens, no latency. // Example: // lastCheckTimestamp: 2024-03-26 19:47:34.000 // currentTimestamp: 2024-03-26 19:47:35.000 - case - lastCheckTimestamp == currentTimestamp-1: + case currentTimestamp - 1: lastCheckTimestamp = currentTimestamp // Latency in 3 seconds, which can be tolerant. // Example: // lastCheckTimestamp: 2024-03-26 19:47:31.000、2024-03-26 19:47:32.000 // currentTimestamp: 2024-03-26 19:47:34.000 - case - lastCheckTimestamp == currentTimestamp-2, - lastCheckTimestamp == currentTimestamp-3: + case currentTimestamp - 2, currentTimestamp - 3: lastCheckTimestamp += 1 // Too much latency, it ignores the fix, the cron job might not be triggered. diff --git a/os/gfile/gfile_search.go b/os/gfile/gfile_search.go index a0d06999de2..3627c3f268e 100644 --- a/os/gfile/gfile_search.go +++ b/os/gfile/gfile_search.go @@ -46,10 +46,10 @@ func Search(name string, prioritySearchPaths ...string) (realPath string, err er // If it fails searching, it returns formatted error. if realPath == "" { buffer := bytes.NewBuffer(nil) - buffer.WriteString(fmt.Sprintf(`cannot find "%s" in following paths:`, name)) + fmt.Fprintf(buffer, `cannot find "%s" in following paths:`, name) array.RLockFunc(func(array []string) { for k, v := range array { - buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v)) + fmt.Fprintf(buffer, "\n%d. %s", k+1, v) } }) err = gerror.New(buffer.String()) diff --git a/os/gres/gres_func_zip.go b/os/gres/gres_func_zip.go index bd2f1f65c78..f193bfb151d 100644 --- a/os/gres/gres_func_zip.go +++ b/os/gres/gres_func_zip.go @@ -63,7 +63,7 @@ func doZipPathWriter(srcPath string, zipWriter *zip.Writer, option ...Option) er files = []string{absolutePath} } headerPrefix := usedOption.Prefix - if !(headerPrefix == "/") { + if headerPrefix != "/" { headerPrefix = strings.TrimRight(headerPrefix, `\/`) } if headerPrefix != "" && gfile.IsDir(absolutePath) { @@ -124,8 +124,7 @@ func zipFile(path string, prefix string, zw *zip.Writer) error { prefix = strings.ReplaceAll(prefix, `//`, `/`) file, err := os.Open(path) if err != nil { - err = gerror.Wrapf(err, `os.Open failed for path "%s"`, path) - return nil + return gerror.Wrapf(err, `os.Open failed for path "%s"`, path) } defer file.Close() diff --git a/os/gspath/gspath.go b/os/gspath/gspath.go index 0ccced9f718..051ef2f2ee1 100644 --- a/os/gspath/gspath.go +++ b/os/gspath/gspath.go @@ -52,9 +52,7 @@ func New(path string, cache bool) *SPath { sp.cache = gmap.NewStrStrMap(true) } if len(path) > 0 { - if _, err := sp.Add(path); err != nil { - // intlog.Print(err) - } + _, _ = sp.Add(path) } return sp } diff --git a/os/gtime/gtime.go b/os/gtime/gtime.go index f09ed0eff19..12f0346751e 100644 --- a/os/gtime/gtime.go +++ b/os/gtime/gtime.go @@ -31,7 +31,7 @@ const ( H = time.Hour M = time.Minute S = time.Second - MS = time.Millisecond + MS = time.Millisecond //nolint:staticcheck US = time.Microsecond NS = time.Nanosecond diff --git a/os/gtime/gtime_time.go b/os/gtime/gtime_time.go index 9766446340c..881accce48b 100644 --- a/os/gtime/gtime_time.go +++ b/os/gtime/gtime_time.go @@ -460,7 +460,7 @@ func (t *Time) StartOfHalf() *Time { func (t *Time) StartOfYear() *Time { y, _, _ := t.Date() newTime := t.Clone() - newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Time.Location()) + newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Location()) return newTime } @@ -487,7 +487,7 @@ func (t *Time) EndOfDay(withNanoPrecision ...bool) *Time { y, m, d := t.Date() newTime := t.Clone() newTime.Time = time.Date( - y, m, d, 23, 59, 59, int(time.Second-getPrecisionDelta(withNanoPrecision...)), newTime.Time.Location(), + y, m, d, 23, 59, 59, int(time.Second-getPrecisionDelta(withNanoPrecision...)), newTime.Location(), ) return newTime } diff --git a/os/gtime/gtime_time_zone.go b/os/gtime/gtime_time_zone.go index ce6a8c03696..79065b2380a 100644 --- a/os/gtime/gtime_time_zone.go +++ b/os/gtime/gtime_time_zone.go @@ -81,7 +81,7 @@ func SetTimeZone(zone string) (err error) { // ToLocation converts current time to specified location. func (t *Time) ToLocation(location *time.Location) *Time { newTime := t.Clone() - newTime.Time = newTime.Time.In(location) + newTime.Time = newTime.In(location) return newTime } diff --git a/os/gview/gview_config.go b/os/gview/gview_config.go index 4bf41b5f7db..a309a041c5b 100644 --- a/os/gview/gview_config.go +++ b/os/gview/gview_config.go @@ -86,9 +86,9 @@ func (view *View) SetConfigWithMap(m map[string]any) error { _, v1 := gutil.MapPossibleItemByKey(m, "paths") _, v2 := gutil.MapPossibleItemByKey(m, "path") if v1 == nil && v2 != nil { - switch v2.(type) { + switch v2 := v2.(type) { case string: - m["paths"] = []string{v2.(string)} + m["paths"] = []string{v2} case []string: m["paths"] = v2 } diff --git a/os/gview/gview_parse.go b/os/gview/gview_parse.go index 364a065add4..02d2888b013 100644 --- a/os/gview/gview_parse.go +++ b/os/gview/gview_parse.go @@ -444,22 +444,21 @@ func (view *View) searchFile(ctx context.Context, file string) (path string, fol if path == "" { buffer := bytes.NewBuffer(nil) if view.searchPaths.Len() > 0 { - buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" in following paths:", file)) + fmt.Fprintf(buffer, "cannot find template file \"%s\" in following paths:", file) view.searchPaths.RLockFunc(func(array []string) { index := 1 for _, searchPath := range array { searchPath = gstr.TrimRight(searchPath, `\/`) for _, tryFolder := range localSystemTryFolders { - buffer.WriteString(fmt.Sprintf( + fmt.Fprintf(buffer, "\n%d. %s", - index, gfile.Join(searchPath, tryFolder), - )) + index, gfile.Join(searchPath, tryFolder)) index++ } } }) } else { - buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" with no path set/add", file)) + fmt.Fprintf(buffer, "cannot find template file \"%s\" with no path set/add", file) } if errorPrint() { glog.Error(ctx, buffer.String()) diff --git a/text/gstr/gstr_convert.go b/text/gstr/gstr_convert.go index 4bf221b31cf..c102402ecf1 100644 --- a/text/gstr/gstr_convert.go +++ b/text/gstr/gstr_convert.go @@ -9,7 +9,6 @@ package gstr import ( "bytes" "fmt" - "math" "regexp" "strconv" "strings" @@ -135,30 +134,57 @@ func Shuffle(str string) string { // HideStr replaces part of the string `str` to `hide` by `percentage` from the `middle`. // It considers parameter `str` as unicode string. func HideStr(str string, percent int, hide string) string { - array := strings.Split(str, "@") - if len(array) > 1 { - str = array[0] + // Handle email case + var suffix string + if idx := strings.IndexByte(str, '@'); idx >= 0 { + suffix = str[idx:] + str = str[:idx] } - var ( - rs = []rune(str) - length = len(rs) - mid = math.Floor(float64(length / 2)) - hideLen = int(math.Floor(float64(length) * (float64(percent) / 100))) - start = int(mid - math.Floor(float64(hideLen)/2)) - hideStr = []rune("") - hideRune = []rune(hide) - ) - for i := 0; i < hideLen; i++ { - hideStr = append(hideStr, hideRune...) + + // Early return for edge cases + if str == "" || percent <= 0 { + return str + suffix + } + if percent >= 100 { + return strings.Repeat(hide, len([]rune(str))) + suffix + } + + rs := []rune(str) + length := len(rs) + if length == 0 { + return str + suffix + } + + // Calculate hideLen using the same logic as original (with floor) + hideLen := (length * percent) / 100 + if hideLen == 0 { + return str + suffix } - buffer := bytes.NewBuffer(nil) - buffer.WriteString(string(rs[0:start])) - buffer.WriteString(string(hideStr)) - buffer.WriteString(string(rs[start+hideLen:])) - if len(array) > 1 { - buffer.WriteString("@" + array[1]) + + // Calculate start position: mid - hideLen/2 + // This matches the original algorithm behavior + mid := length / 2 + start := max(mid-hideLen/2, 0) + + end := start + hideLen + if end > length { + end = length + start = max(length-hideLen, 0) } - return buffer.String() + + // Pre-calculate capacity to avoid reallocations + var builder strings.Builder + builder.Grow(len(str) + len(hide)*hideLen + len(suffix)) + + // Build result string efficiently + builder.WriteString(string(rs[:start])) + if hide != "" { + builder.WriteString(strings.Repeat(hide, hideLen)) + } + builder.WriteString(string(rs[end:])) + builder.WriteString(suffix) + + return builder.String() } // Nl2Br inserts HTML line breaks(`br`|
) before all newlines in a string: @@ -207,9 +233,8 @@ func WordWrap(str string, width int, br string) string { wordBuf, spaceBuf bytes.Buffer init = make([]byte, 0, len(str)) buf = bytes.NewBuffer(init) - strRunes = []rune(str) ) - for _, char := range strRunes { + for _, char := range str { switch { case char == '\n': if wordBuf.Len() == 0 { diff --git a/text/gstr/gstr_count.go b/text/gstr/gstr_count.go index cd0f0a19ecf..16b40fa231f 100644 --- a/text/gstr/gstr_count.go +++ b/text/gstr/gstr_count.go @@ -29,7 +29,7 @@ func CountI(s, substr string) int { func CountWords(str string) map[string]int { m := make(map[string]int) buffer := bytes.NewBuffer(nil) - for _, r := range []rune(str) { + for _, r := range str { if unicode.IsSpace(r) { if buffer.Len() > 0 { m[buffer.String()]++ @@ -46,14 +46,11 @@ func CountWords(str string) map[string]int { } // CountChars returns information about chars' count used in a string. -// It considers parameter `str` as unicode string. +// It considers parameter `str` as Unicode string. func CountChars(str string, noSpace ...bool) map[string]int { m := make(map[string]int) - countSpace := true - if len(noSpace) > 0 && noSpace[0] { - countSpace = false - } - for _, r := range []rune(str) { + countSpace := len(noSpace) == 0 || !noSpace[0] + for _, r := range str { if !countSpace && unicode.IsSpace(r) { continue } diff --git a/text/gstr/gstr_similar.go b/text/gstr/gstr_similar.go index 7c19618fb6c..cc7619906a1 100644 --- a/text/gstr/gstr_similar.go +++ b/text/gstr/gstr_similar.go @@ -25,7 +25,6 @@ func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int { return -1 } - tmp := make([]int, l2+1) p1 := make([]int, l2+1) p2 := make([]int, l2+1) var c0, c1, c2 int @@ -51,9 +50,7 @@ func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int { } p2[i2+1] = c0 } - tmp = p1 - p1 = p2 - p2 = tmp + p1, p2 = p2, p1 } c0 = p1[l2] diff --git a/text/gstr/gstr_upper_lower.go b/text/gstr/gstr_upper_lower.go index 69ad78c11d5..dd154ac001b 100644 --- a/text/gstr/gstr_upper_lower.go +++ b/text/gstr/gstr_upper_lower.go @@ -9,6 +9,9 @@ package gstr import ( "strings" + "golang.org/x/text/cases" + "golang.org/x/text/language" + "github.com/gogf/gf/v2/internal/utils" ) @@ -40,7 +43,7 @@ func LcFirst(s string) string { // UcWords uppercase the first character of each word in a string. func UcWords(str string) string { - return strings.Title(str) + return cases.Title(language.Und).String(str) } // IsLetterLower tests whether the given byte b is in lower case. diff --git a/text/gstr/gstr_z_unit_test.go b/text/gstr/gstr_z_unit_test.go index 63780d8e05f..3f9c37a19c0 100644 --- a/text/gstr/gstr_z_unit_test.go +++ b/text/gstr/gstr_z_unit_test.go @@ -54,7 +54,7 @@ func Test_LcFirst(t *testing.T) { func Test_UcWords(t *testing.T) { gtest.C(t, func(t *gtest.T) { s1 := "我爱GF: i love go frame" - e1 := "我爱GF: I Love Go Frame" + e1 := "我爱Gf: I Love Go Frame" t.Assert(gstr.UcWords(s1), e1) }) } @@ -178,9 +178,9 @@ func Test_SplitAndTrim(t *testing.T) { gtest.C(t, func(t *gtest.T) { s := ` -010 +010 -020 +020 ` a := gstr.SplitAndTrim(s, "\n", "0") @@ -321,6 +321,35 @@ func Test_HideStr(t *testing.T) { t.Assert(gstr.HideStr("张三", 50, "*"), "张*") t.Assert(gstr.HideStr("张小三", 50, "*"), "张*三") t.Assert(gstr.HideStr("欧阳小三", 50, "*"), "欧**三") + + // 边界与特殊用例扩展 + // 1) 空字符串与非正百分比 + t.Assert(gstr.HideStr("", 50, "*"), "") + t.Assert(gstr.HideStr("abcdef", 0, "*"), "abcdef") + t.Assert(gstr.HideStr("abcdef", -1, "*"), "abcdef") + + // 2) 百分比为100(完全隐藏),邮箱仅隐藏本地部分 + t.Assert(gstr.HideStr("abcdef", 100, "*"), "******") + t.Assert(gstr.HideStr("user@example.com", 100, "*"), "****@example.com") + + // 3) 极短字符串 + t.Assert(gstr.HideStr("a", 100, "*"), "*") + t.Assert(gstr.HideStr("ab", 50, "*"), "a*") + // 百分比太小时(四舍五入前为0),应保持不变 + t.Assert(gstr.HideStr("ab", 10, "*"), "ab") + + // 4) 隐藏字符为空:相当于删除中间片段 + t.Assert(gstr.HideStr("abcdef", 50, ""), "abf") + t.Assert(gstr.HideStr("john@kohg.cn", 50, ""), "jn@kohg.cn") + + // 5) 多字符隐藏串 + t.Assert(gstr.HideStr("abcde", 40, "##"), "a####de") + + // 6) Unicode/emoji + t.Assert(gstr.HideStr("你好🙂世界", 40, "*"), "你**世界") + + // 7) 多个@的字符串,按第一个@处理 + t.Assert(gstr.HideStr("a@b@c", 100, "*"), "*@b@c") }) } diff --git a/util/gconv/gconv_scan_list.go b/util/gconv/gconv_scan_list.go index 40bbefab9d3..404faf15d88 100644 --- a/util/gconv/gconv_scan_list.go +++ b/util/gconv/gconv_scan_list.go @@ -271,7 +271,7 @@ func doScanList( arrayElemValue = reflect.New(arrayItemType.Elem()).Elem() arrayValue.Index(i).Set(arrayElemValue.Addr()) } - } else { + // } else { // Like: []Entity } bindToAttrValue = arrayElemValue.FieldByName(bindToAttrName) diff --git a/util/gconv/internal/converter/converter_int.go b/util/gconv/internal/converter/converter_int.go index c538713d01d..4f28cdcf934 100644 --- a/util/gconv/internal/converter/converter_int.go +++ b/util/gconv/internal/converter/converter_int.go @@ -108,10 +108,11 @@ func (c *Converter) Int64(anyInput any) (int64, error) { isMinus = false ) if len(s) > 0 { - if s[0] == '-' { + switch s[0] { + case '-': isMinus = true s = s[1:] - } else if s[0] == '+' { + case '+': s = s[1:] } } diff --git a/util/gconv/internal/converter/converter_scan.go b/util/gconv/internal/converter/converter_scan.go index 40bb65dfbc8..6a8e8c4b40d 100644 --- a/util/gconv/internal/converter/converter_scan.go +++ b/util/gconv/internal/converter/converter_scan.go @@ -67,6 +67,7 @@ func (c *Converter) Scan(srcValue any, dstPointer any, option ...ScanOption) (er if dstPointerReflectValue.CanAddr() { dstPointerReflectValue = dstPointerReflectValue.Addr() dstPointerReflectType = dstPointerReflectValue.Type() + // dstPointerReflectKind = dstPointerReflectType.Kind() } else { // If dstPointer is not a pointer and cannot be addressed, return an error return gerror.NewCodef( diff --git a/util/gpage/gpage.go b/util/gpage/gpage.go index adcb3eb7399..9b554043630 100644 --- a/util/gpage/gpage.go +++ b/util/gpage/gpage.go @@ -111,7 +111,7 @@ func (p *Page) LastPage() string { // PageBar returns the HTML page bar content with link and span tags. func (p *Page) PageBar() string { - plus := int(math.Ceil(float64(p.PageBarNum / 2))) + plus := p.PageBarNum / 2 if p.PageBarNum-plus+p.CurrentPage > p.TotalPage { plus = p.PageBarNum - p.TotalPage + p.CurrentPage } diff --git a/util/gutil/gutil_dump.go b/util/gutil/gutil_dump.go index 1d0332966a6..7aca81b5d1b 100644 --- a/util/gutil/gutil_dump.go +++ b/util/gutil/gutil_dump.go @@ -176,13 +176,13 @@ func doDump(value any, indent string, buffer *bytes.Buffer, option doDumpOption) doDumpNumber(exportInternalInput) case reflect.Chan: - buffer.WriteString(fmt.Sprintf(`<%s>`, reflectValue.Type().String())) + fmt.Fprintf(buffer, `<%s>`, reflectValue.Type().String()) case reflect.Func: if reflectValue.IsNil() || !reflectValue.IsValid() { buffer.WriteString(``) } else { - buffer.WriteString(fmt.Sprintf(`<%s>`, reflectValue.Type().String())) + fmt.Fprintf(buffer, `<%s>`, reflectValue.Type().String()) } case reflect.Interface: @@ -209,14 +209,9 @@ type doDumpInternalInput struct { func doDumpSlice(in doDumpInternalInput) { if b, ok := in.Value.([]byte); ok { if !in.Option.WithType { - in.Buffer.WriteString(fmt.Sprintf(`"%s"`, addSlashesForString(string(b)))) + fmt.Fprintf(in.Buffer, `"%s"`, addSlashesForString(string(b))) } else { - in.Buffer.WriteString(fmt.Sprintf( - `%s(%d) "%s"`, - in.ReflectTypeName, - len(string(b)), - string(b), - )) + fmt.Fprintf(in.Buffer, `%s(%d) "%s"`, in.ReflectTypeName, len(string(b)), string(b)) } return } @@ -224,21 +219,21 @@ func doDumpSlice(in doDumpInternalInput) { if !in.Option.WithType { in.Buffer.WriteString("[]") } else { - in.Buffer.WriteString(fmt.Sprintf("%s(0) []", in.ReflectTypeName)) + fmt.Fprintf(in.Buffer, "%s(0) []", in.ReflectTypeName) } return } if !in.Option.WithType { in.Buffer.WriteString("[\n") } else { - in.Buffer.WriteString(fmt.Sprintf("%s(%d) [\n", in.ReflectTypeName, in.ReflectValue.Len())) + fmt.Fprintf(in.Buffer, "%s(%d) [\n", in.ReflectTypeName, in.ReflectValue.Len()) } for i := 0; i < in.ReflectValue.Len(); i++ { in.Buffer.WriteString(in.NewIndent) doDump(in.ReflectValue.Index(i), in.NewIndent, in.Buffer, in.Option) in.Buffer.WriteString(",\n") } - in.Buffer.WriteString(fmt.Sprintf("%s]", in.Indent)) + fmt.Fprintf(in.Buffer, "%s]", in.Indent) } func doDumpMap(in doDumpInternalInput) { @@ -254,7 +249,7 @@ func doDumpMap(in doDumpInternalInput) { if !in.Option.WithType { in.Buffer.WriteString("{}") } else { - in.Buffer.WriteString(fmt.Sprintf("%s(0) {}", in.ReflectTypeName)) + fmt.Fprintf(in.Buffer, "%s(0) {}", in.ReflectTypeName) } return } @@ -272,7 +267,7 @@ func doDumpMap(in doDumpInternalInput) { if !in.Option.WithType { in.Buffer.WriteString("{\n") } else { - in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(mapKeys))) + fmt.Fprintf(in.Buffer, "%s(%d) {\n", in.ReflectTypeName, len(mapKeys)) } for _, mapKey := range mapKeys { tmpSpaceNum = len(fmt.Sprintf(`%v`, mapKey.Interface())) @@ -283,32 +278,34 @@ func doDumpMap(in doDumpInternalInput) { } // Map key and indent string dump. if !in.Option.WithType { - in.Buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + in.Buffer, "%s%v:%s", in.NewIndent, mapKeyStr, strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) + ) } else { - in.Buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + in.Buffer, "%s%s(%v):%s", in.NewIndent, mapKey.Type().String(), mapKeyStr, strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) + ) } // Map value dump. doDump(in.ReflectValue.MapIndex(mapKey), in.NewIndent, in.Buffer, in.Option) in.Buffer.WriteString(",\n") } - in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent)) + fmt.Fprintf(in.Buffer, "%s}", in.Indent) } func doDumpStruct(in doDumpInternalInput) { if in.PtrAddress != "" { if _, ok := in.DumpedPointerSet[in.PtrAddress]; ok { - in.Buffer.WriteString(fmt.Sprintf(``, in.PtrAddress)) + fmt.Fprintf(in.Buffer, ``, in.PtrAddress) return } } @@ -355,12 +352,13 @@ func doDumpStruct(in doDumpInternalInput) { if !in.Option.WithType { in.Buffer.WriteString(structContentStr) } else { - in.Buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + in.Buffer, "%s(%s) %s", in.ReflectTypeName, attributeCountStr, structContentStr, - )) + ) } return } @@ -382,37 +380,39 @@ dumpStructFields: if !in.Option.WithType { in.Buffer.WriteString("{\n") } else { - in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(structFields))) + fmt.Fprintf(in.Buffer, "%s(%d) {\n", in.ReflectTypeName, len(structFields)) } for _, field := range structFields { if in.ExportedOnly && !field.IsExported() { continue } tmpSpaceNum = len(fmt.Sprintf(`%v`, field.Name())) - in.Buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + in.Buffer, "%s%s:%s", in.NewIndent, field.Name(), strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) + ) doDump(field.Value, in.NewIndent, in.Buffer, in.Option) in.Buffer.WriteString(",\n") } - in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent)) + fmt.Fprintf(in.Buffer, "%s}", in.Indent) } func doDumpNumber(in doDumpInternalInput) { if v, ok := in.Value.(iString); ok { s := v.String() if !in.Option.WithType { - in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s))) + fmt.Fprintf(in.Buffer, `"%v"`, addSlashesForString(s)) } else { - in.Buffer.WriteString(fmt.Sprintf( - `%s(%d) "%v"`, + fmt.Fprintf( + in.Buffer, + "%s(%d) %s", in.ReflectTypeName, len(s), - addSlashesForString(s), - )) + fmt.Sprintf(`"%v"`, addSlashesForString(s)), + ) } } else { doDumpDefault(in) @@ -422,14 +422,15 @@ func doDumpNumber(in doDumpInternalInput) { func doDumpString(in doDumpInternalInput) { s := in.ReflectValue.String() if !in.Option.WithType { - in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s))) + fmt.Fprintf(in.Buffer, `"%v"`, addSlashesForString(s)) } else { - in.Buffer.WriteString(fmt.Sprintf( + fmt.Fprintf( + in.Buffer, `%s(%d) "%v"`, in.ReflectTypeName, len(s), addSlashesForString(s), - )) + ) } } @@ -458,7 +459,7 @@ func doDumpDefault(in doDumpInternalInput) { if !in.Option.WithType { in.Buffer.WriteString(s) } else { - in.Buffer.WriteString(fmt.Sprintf("%s(%s)", in.ReflectTypeName, s)) + fmt.Fprintf(in.Buffer, "%s(%s)", in.ReflectTypeName, s) } }