いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-542 (strings.Lines)(Go 1.24で追加された関数)

関連記事

Goメモ-541 (bytes.Lines)(Go 1.24で追加された関数) - いろいろ備忘録日記

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。

Go 1.24にて、stringsパッケージに strings.Lines という関数が追加されました。

https://pkg.go.dev/strings@go1.24.0#Lines

Lines returns an iterator over the newline-terminated lines in the string s. The lines yielded by the iterator include their terminating newlines. If s is empty, the iterator yields no lines at all. If s does not end in a newline, the final yielded line will not end in a newline. It returns a single-use iterator.

(Linesは、文字列s中の改行で終端された行に対するイテレータを返す。イテレータが返す行には、終端の改行も含まれる。 s が空の場合、イテレータは行を返さない。 s が改行で終わらない場合、最終的に得られる行は改行で終わらない。 これは1回限りのイテレータを返します。)

名前の通り、引数に指定した文字列を \n で区切ったイテレータを返してくれます。

Go 1.23で追加されたイテレータが活用されてますね。

使い方は自明なのですが、一応自分用にサンプルを以下にメモしておきます。

サンプル

package strs

import (
    "fmt"
    "iter"
    "os"
    "strings"
    "unsafe"
)

// Go124StringsLines は、Go 1.24 で追加された strings.Lines() のサンプルです.
//
// Go 1.23 で追加されたイテレータを返すようになっています。
// strings.Lines()は、文字列を '\n' で区切ったデータをイテレータで提供してくれます。
// このデータには '\n' 自身も付いた状態で取得出来るので、その点には注意が必要。
// (fmt.Println()でそのまま出力すると2個改行が入ることになる)
//
// # REFERENCES
//   - https://pkg.go.dev/strings@go1.24.0#Lines
//   - https://tip.golang.org/doc/go1.24#stringspkgstrings
//   - https://tip.golang.org/doc/go1.23#iterators
func Go124StringsLines() error {
    var (
        // 最初のN行のみに絞るためのイテレータ関数
        firstN = func(n int, lines iter.Seq[string]) iter.Seq[string] {
            return func(yield func(string) bool) {
                count := 0
                for line := range lines {
                    if count >= n || !yield(line) {
                        return
                    }

                    count++
                }
            }
        }
        // 前に番号を付与するイテレータ
        withLineNum = func(lines iter.Seq[string]) iter.Seq[string] {
            return func(yield func(string) bool) {
                count := 1
                for line := range lines {
                    if !yield(fmt.Sprintf("%2d: %s", count, line)) {
                        return
                    }

                    count++
                }
            }
        }
        // []byteからstringへ変換するためのヘルパー関数
        toStr = func(b []byte) string {
            return unsafe.String(unsafe.SliceData(b), len(b))
        }

        data, _ = os.ReadFile("README.md")   // ファイルデータを読み出して
        lines   = strings.Lines(toStr(data)) // 行単位にして
        first5  = firstN(5, lines)           // 先頭5行のみにして
        withNum = withLineNum(first5)        // 行番号を付与
    )

    for line := range withNum {
        fmt.Printf("%s", line)
    }

    return nil
}

実行すると以下のようになります。

$ task
task: [build] go build -o "/workspace/try-golang/try-golang" .
task: [run] ./try-golang -onetime

ENTER EXAMPLE NAME: string_go124_strings_lines

[Name] "string_go124_strings_lines"
 1: 
 2: # try-golang
 3: 
 4: This is my TUTORIAL project for golang.
 5: 


[Elapsed] 85.64µs

参考情報

Goメモ-540 (Go 1.24 リリース)(参考情報リンク) - いろいろ備忘録日記

個人的Goのおすすめ書籍

個人的に読んでとても勉強になった書籍さんたちです。


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。