Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
golang.org/x/text/transformを用いた文字列変換のススメ
Search
tom twinkle
December 09, 2022
Programming
0
11k
golang.org/x/text/transformを用いた文字列変換のススメ
golang.org/x/text/transformを使ったcustom transformの作成の仕方
tom twinkle
December 09, 2022
Tweet
Share
Other Decks in Programming
See All in Programming
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
450
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
390
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
1
690
Haskell でアルゴリズムを抽象化する / 関数型言語で競技プログラミング
naoya
17
4.9k
すべてのコンテキストを、 ユーザー価値に変える
applism118
2
800
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
360
技術同人誌をMCP Serverにしてみた
74th
1
360
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
uki00a
0
150
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
260
Cline指示通りに動かない? AI小説エージェントで学ぶ指示書の書き方と自動アップデートの仕組み
kamomeashizawa
1
580
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
2
270
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
250
Featured
See All Featured
How to Ace a Technical Interview
jacobian
277
23k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
330
24k
Bash Introduction
62gerente
614
210k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
4 Signs Your Business is Dying
shpigford
184
22k
Rails Girls Zürich Keynote
gr2m
94
14k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
A Modern Web Designer's Workflow
chriscoyier
694
190k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Speed Design
sergeychernyshev
32
1k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Transcript
golang.org/x/text/transformを用いた文 字列変換のススメ ANDPAD inc. tomoki.harada (tomtwinkle) Let’s transform!
transform.Transformer使っていますか?
transform.Transformer とは
https://pkg.go.dev/golang.org/x/text @v0.4.0/transform
something output something output io.Writer io.Reader Transformer Transformer https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=110 https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=209
transform.Writer transform.Reader something input something input “abc” [\x97,\x98,\x99] “adc” [\x97,\x100,\x99] “b” -> “d” \x98 -> \x100 全てのbyte列をメモリに載せなくても Streamのまま部分的にbyte列を操作できる
• メモリ使用量を抑える • memory allocation, GCによる速度 低下を避ける
それっぽいキーワードで探してもあまり見つからない
transform.Transformer 実装の仕方
https://cs.opensource.google/go/x/text/+/internal-branch.g o1.19-vendor:transform/transform.go;l=41 byte列の変換処理 Transformer再利用の為のリセットメソッド (Transformer内部state変数の値リセット)
https://cs.opensource.google/go/x/text/+/internal-branch.g o1.19-vendor:transform/transform.go;l=104 Transformer内部でstateを持たない場合はResetの実装が不要なので NopResetterをstructにEmbedded
https://cs.opensource.google/go/x/text/+/internal-branch.g o1.19-vendor:transform/transform.go;l=41
something output something output io.Writer Buffer Transform() Transform() https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=110 https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=209
transform.Writer transform.Reader something input something input Buffer io.Reader srcのbyte列 もっと欲しい → ErrShortSrc dstのbuffer size足りてない → ErrShortDst
Transformの戻り値のerrorについて Error Type 説明 transform.ErrShortDst srcの入力に対してdst bufferが不足している際に返却する Transformerはdst bufferをioに一旦書き込み、またdst bufferを空にしてTransformを呼び出す
これを返さないと4096byte以上処理できない transform.ErrShortSrc Streamでやってきたsrcの入力情報だけでは不足していて処 理出来ず次のsrcも読み込む必要がある場合に返却する (Hello->Hiに変換する処理でHellしかinputにない等) 当然、ErrShortDstとかち合うのでdst bufferよりも小さいの が前提
something output something output io.Writer Buffer Transform() Transform() https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=110 https://cs.opensource.google/go/x/text/+/refs/tags/v0.4.0:transform/transform.go;l=209
transform.Writer transform.Reader something input something input Buffer io.Reader nDst=dstに格 納したbyte数 nSrc=srcから dstにcopyした byte数
https://go.dev/play/p/ezCskczrmlf 何も変換しないNop Transformer
https://go.dev/play/p/T7G8n-kNrNW 何も変換しないNop Transformer
https://github.com/tomtwinkle/garbledreplacer UTF-8からShift-JISに変換する際に出来ない文字を置き換えるTransformer
準パッケージのTransformerは変換出来ないとerrorになってしまう
https://github.com/tomtwinkle/garbledreplacer UTF-8からShift-JISに変換する際に出来ない文字を置き換えるTransformer transformに渡されるbyte列が文字列であるとは限ら ないため文字列かどうかの判定を行う srcが最後のbyte列の場合はatEOF=trueになる このロジック上では無くても動作上問題ないが、余計な処理が走らないよう にearly returnしている runeがShift-JISでencode出来るかチェック encode出来なかったら別の文字に置き換え
変換後のbyte列がdstのbufferからあふれる場合は dstに copyせずにErrShortDstを返して次の処理に回す nDstの値を適切に返していれば次回の処理では未処理の byte列を繋げて返してくれます ←!! マルチバイト文字注意ポイント マルチバイト文字の途中で srcが途切れた場合は そのbyte列をdstにcopyしないように調整が必要です
今まで作成したTransformer • UTF-8をShift-JISに変換し、変換できない文字を置き換 える https://github.com/tomtwinkle/garbledreplacer • UTF-8 BOMを削除する https://github.com/tomtwinkle/utfbomremover •
特定の文字列を別の文字列に変換 https://github.com/tomtwinkle/gostrreplacer
おまけ
私選!Githubで公開されている面白Transformer • 特定の文字列を別の文字列に変換 https://github.com/tenntenn/text ℳ → M • Windows向けのCodePage Decoder
https://github.com/mattn/go-localereader CP932(Shift-JIS), CP1200(UTF-16), CP65001(UTF-8) • ニーモニックEncoder/Decoder(パスワード等の乱数のような意味のな い英数字を理解しやすい単語に変換して電話越しで伝えやすくする) https://github.com/schollz/mnemonicode こんな感じの変換 8f9240688685a1e9 ↔ magic-slang-crimson--inch-calypso-ibiza
面白Transformer番外編 • uber-go/configシェルライクなシークエンス(${hoge}みたいな記述) を展開する実装 https://github.com/uber-go/config/blob/v1.4.0/expand.go#L124 • andybalholm/redwood tgulacsi/go文字列内で重複するスペースを削 除する実装 https://github.com/andybalholm/redwood/blob/v1.7.0/word.go#L53
https://github.com/tgulacsi/go/blob/v0.24.0/stream/trim.go#L39 • BurntSushi/graphics-go 画像をアフィン変換する実装 https://github.com/BurntSushi/graphics-go/blob/master/graphics/affine.go#L61
マルチバイト文字を扱うアジア圏の我々 だからこそTransformerを賢く扱ってい きましょう! (もっと情報が増えて欲しい…!)