0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Go] strings: illegal use of non-zero Builder copied by value

Posted at

事の発端

こんな雰囲気のコードを書いていました。
※記事用に簡略化しています

package main

import (
	"fmt"
	"strings"
)

func main() {
	sb := strings.Builder{}
	sb.Grow(30)

	returnedStr := BuildString(sb)
	fmt.Println(returnedStr)
}


func BuildString(sb strings.Builder) string {
	strSlice := []string{"a", "s", "d", "f", "g", "h"}
	for _, s := range strSlice{
		sb.WriteString(s)
	}
	return sb.String()
}

するとこんなエラーが起きます。

$ go run main.go
panic: strings: illegal use of non-zero Builder copied by value
goroutine 1 [running]:
strings.(*Builder).copyCheck(...)
        C:/Program Files/Go/src/strings/builder.go:35
strings.(*Builder).WriteString(...)
        C:/Program Files/Go/src/strings/builder.go:107
main.BuildString(...)
        C:/Users/**/**/**/**/currentDir/main.go:20
main.main()
        C:/Users/**/**/**/**/currentDir/main.go:12 +0x2d0
exit status 2

解決策

これはstrings.Builderを別関数の引数にして別関数で使おうとしたことにより、
BuildString関数の中のWriteStringメソッドの中で定義されているcopyCheck関数でpanicが起きています。

WriteStringメソッド

func (b *Builder) WriteString(s string) (int, error) {
	b.copyCheck()
	b.buf = append(b.buf, s...)
	return len(s), nil
}

その中のcopyCheck関数

func (b *Builder) copyCheck() {
	if b.addr == nil {
		b.addr = (*Builder)(abi.NoEscape(unsafe.Pointer(b)))
	} else if b.addr != b {
		panic("strings: illegal use of non-zero Builder copied by value")
	}
}

この関数のelse if部分に引っかかったのでしょう。
illegal use of non-zero Builder copied by valueと書かれており
翻訳すると「値によりコピーされたゼロでないBuilderの不正使用」とあります。

なので別関数の引数にして別関数で使おうとしたためBuilderの値のみコピーされて別アドレスだったため起きたパニックということでしょうか。

つまりstrings.Builderは定義した関数内で使わなくてはならないのかも。

下記のようにしたらエラーが消えました。

package main

import (
	"fmt"
	"strings"
)

func main() {
	sb := strings.Builder{}
	sb.Grow(30)
	strSlice := []string{"a", "s", "d", "f", "g", "h"}

	for _, s := range strSlice{
		sb.WriteString(s)
	}

	str := sb.String()

	fmt.Println(str)
}
$ go run main.go
asdfgh
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?