Skip to content

bytes, strings: add ContainsFunc #54386

Closed
@itchyny

Description

@itchyny

I propose to add ContainsFunc to package strings and bytes.

// ContainsFunc reports whether any Unicode code points c within s satisfy f(c).
func ContainsFunc(s string, f func(rune) bool) bool {
	return IndexFunc(s, f) >= 0
}

The {bytes,strings}.ContainsFunc functions replace codes which only check whether the string contains a Unicode code point satisfying the condition or not using {bytes,strings}.IndexFunc.

In the Go repository, there are 6 codes (out of 9 using $PKG.IndexFunc(...)) to be replaced by the proposed ContainsFunc functions.

 $ semgrep --quiet --lang=go --pattern='$PKG.IndexFunc(...) >= 0'

Findings:

  src/archive/tar/reader.go
        395if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {


  src/testing/benchmark.go
        353if strings.IndexFunc(unit, unicode.IsSpace) >= 0 {

 $ semgrep --quiet --lang=go --pattern='$PKG.IndexFunc(...) < 0'

Findings:

  src/mime/grammar.go
         31return strings.IndexFunc(s, isNotTokenChar) < 0


  src/net/http/cookie.go
        465return strings.IndexFunc(raw, isNotToken) < 0


  src/text/template/funcs.go
        725if strings.IndexFunc(s, jsIsSpecial) < 0 {

 $ semgrep --quiet --lang=go --pattern='$PKG.IndexFunc(...) == -1'

Findings:

  src/net/http/request.go
        831return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1

In the Kubernetes repository, I find 2 codes (out of 3 using $PKG.IndexFunc(...)).

 $ semgrep --quiet --lang=go --pattern='$PKG.IndexFunc(...) != -1'

Findings:

  staging/src/k8s.io/client-go/rest/request.go
       1068if bytes.IndexFunc(body, func(r rune) bool {
       1069return r < 0x0a
       1070┆ }) != -1 {


  staging/src/k8s.io/kubectl/pkg/describe/describe.go
        349if strings.IndexFunc(field, func(r rune) bool {
        350return !unicode.IsLetter(r) && r != '-'
        351┆ }) != -1 {

Using ContainsFunc in these if statements will definitely improve the code readability. Also, I believe API symmetry reduces the frustration of coding (I cannot explain why there are Contains, ContainsAny, ContainsRune but not ContainsFunc to Go newbies). Currently, we need to translate what we actually want to check into comparison of returned index against numbers (which may lead to pointless discussion of which is better >= 0 or != -1).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions