Skip to content

Commit

Permalink
Merge pull request #709 from devlights:add-strings-clone-example
Browse files Browse the repository at this point in the history
Add strings.Clone example
  • Loading branch information
devlights authored Dec 5, 2023
2 parents 6503d89 + 428a916 commit 5d0597b
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/basic/strs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
|using\_builder.go|string\_using\_builder|strings.Builder を利用したサンプルです.|
|rune\_count.go|string\_rune\_count|utf8.RuneCountInString() のサンプルです.|
|diff\_trimright\_trimsuffix.go|string\_diff\_trimright\_trimsuffix|strings.TrimRight と strings.TrimSuffix のちょっとした違いについてのサンプルです.|
|using\_string\_clone.go|string\_using\_clone|Go 1.18 で追加された strings.Clone() のサンプルです|
1 change: 1 addition & 0 deletions examples/basic/strs/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ func (r *register) Regist(m mapping.ExampleMapping) {
m["string_rune_count"] = RuneCount
m["string_diff_trimright_trimsuffix"] = DiffTrimRightAndTrimSuffix
m["string_cut_prefix_suffix"] = CutPrefixSuffix
m["string_using_clone"] = UsingStringsClone
}
76 changes: 76 additions & 0 deletions examples/basic/strs/using_strings_clone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package strs

import (
"os/exec"
"strings"

"github.com/devlights/gomy/output"
)

// UsingStringsClone は、Go 1.18 で追加された strings.Clone() のサンプルです。
//
// # REFERENCES
// - https://pkg.go.dev/[email protected]#Clone
func UsingStringsClone() error {
//
// strings.Clone() は、Go 1.18 で追加された関数。
// 新たなメモリ割り当ても行われるので、ディープコピーされるイメージ。
// 部分文字列を特定のストアに対して保持するようなシチュエーションで利用できる。
// (Goの標準コンパイラでは、現状元の文字列と部分文字列は同じメモリを共有するようになっているため
// 数が多い、または、文字列のサイズが巨大な場合などにディープコピーしておかないとメモリが残ることなる)
//

const (
NUM_ITEMS = 100
)

var (
l = make([]string, NUM_ITEMS)
)

// 1024バイトのランダム文字列を1000個用意
for i := 0; i < NUM_ITEMS; i++ {
var (
c *exec.Cmd
output []byte
err error
)

c = exec.Command("/bin/bash", "-c", "openssl rand -base64 1024 | tr -d '\n'")
if output, err = c.Output(); err != nil {
return err
}

l[i] = string(output)
}

//
// 各文字列の先頭5文字分を識別子として保持しておく仕様があるとする
//

var (
store1 = make([]string, NUM_ITEMS)
store2 = make([]string, NUM_ITEMS)
)

// 部分文字列を取り出し、そのまま保持
// この場合、元文字列と部分文字列は同じメモリを共有している可能性があるため
// 場合によっては、5バイト分だけじゃなく、文字列全部がメモリに残ったままとなる
for i := 0; i < NUM_ITEMS; i++ {
store1[i] = l[i][:5]
}

// 部分文字列を取り出し、クローンしてから保持
// Go 1.18 で追加された strings.Clone() を利用することで、新たな割当が行われた状態で
// 文字列がクローンされる。なので元文字列全部がメモリに残ることはなくなる
for i := 0; i < NUM_ITEMS; i++ {
store2[i] = strings.Clone(l[i][:5])
}

for i := 0; i < 3; i++ {
output.Stdoutf("[store1]", "%d: %s\n", i, store1[i])
output.Stdoutf("[store2]", "%d: %s\n", i, store2[i])
}

return nil
}

0 comments on commit 5d0597b

Please sign in to comment.