LoginSignup
0
0

More than 5 years have passed since last update.

Goのstrings.BuilderをラップしてJavaのStringBuilder風に

Posted at

お題

Goの1.10からstrings.Builderというのが追加されて文字列連結が効率的になった様子。
ただ、JavaのStringBuilderを使ってきた身からするとメソッドチェーンでつなげていきたい。Goの作法に則っていなくても。
というわけで、お試しでラッパー作ってみた。

開発環境

# OS

$ $ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"

# 言語

$ go version
go version go1.11.4 linux/amd64

実践

strings.Builderラッパー

こんな感じ。


// NewStringBuilder ...
func NewStringBuilder() StringBuilder {
    return &stringBuilder{sb: strings.Builder{}, anyErrors: []error{}}
}

// StringBuilder ...
type StringBuilder interface {
    Append(str string) StringBuilder
    AppendInt(num int) StringBuilder
    ToString() string
    Errors() []error
}

type stringBuilder struct {
    sb        strings.Builder
    anyErrors []error
}

// Append ...
func (b *stringBuilder) Append(str string) StringBuilder {
    _, err := b.sb.WriteString(str)
    if err != nil {
        b.anyErrors = append(b.anyErrors, err)
    }
    return b
}

// AppendInt ...
func (b *stringBuilder) AppendInt(num int) StringBuilder {
    _, err := b.sb.WriteString(fmt.Sprintf("%d", num))
    if err != nil {
        b.anyErrors = append(b.anyErrors, err)
    }
    return b
}

// ToString ...
func (b *stringBuilder) ToString() string {
    if len(b.anyErrors) > 0 {
        return ""
    }
    return b.sb.String()
}

// Errors ...
func (b *stringBuilder) Errors() []error {
    return b.anyErrors
}

ただラップして、ご丁寧にWriteStringAppendと呼び変え、WriteStringerrorを返すので、返されたエラーをいったん溜めておくようにしただけ。

実行

以下のようにmainで実行

type book struct {
    ID     int
    Name   string
    Author string
    Price  int
}

func main() {
    b := book{
        ID:     1,
        Name:   "何かの本",
        Author: "著者A",
        Price:  100,
    }

    builder := NewStringBuilder()
    jsonLog := builder.
        Append(`{`).
        Append(`"book": {`).
        Append(`"id": `).AppendInt(b.ID).Append(", ").
        Append(`"name": `).Append(b.Name).Append(", ").
        Append(`"author": `).Append(b.Author).Append(", ").
        Append(`"price": `).AppendInt(b.Price).Append("").
        Append(`}`).
        Append(`}`).
        ToString()

    fmt.Println(jsonLog)
}

実行結果

{"book": {"id": 1, "name": 何かの本, "author": 著者A, "price": 100}}

まとめ

Goの「エラーを戻り値で返す主義」と「メソッドチェーン」は、やっぱり相容れないものがある。
Goらしく書くならメソッドチェーンは避けるべきかな。。。

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