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
Azure SRE Agentで運用は楽になるのか?
kkamegawa
0
2.4k
詳解!defer panic recover のしくみ / Understanding defer, panic, and recover
convto
0
250
AIでLINEスタンプを作ってみた
eycjur
1
230
Laravel Boost 超入門
fire_arlo
3
220
基礎から学ぶ大画面対応(Learning Large-Screen Support from the Ground Up)
tomoya0x00
0
3.2k
意外と簡単!?フロントエンドでパスキー認証を実現する WebAuthn
teamlab
PRO
2
770
Oracle Database Technology Night 92 Database Connection control FAN-AC
oracle4engineer
PRO
1
460
プロポーザル駆動学習 / Proposal-Driven Learning
mackey0225
2
1.3k
チームのテスト力を鍛える
goyoki
3
760
Ruby Parser progress report 2025
yui_knk
1
450
rage against annotate_predecessor
junk0612
0
170
AIを活用し、今後に備えるための技術知識 / Basic Knowledge to Utilize AI
kishida
22
5.8k
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.6k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
We Have a Design System, Now What?
morganepeng
53
7.8k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Navigating Team Friction
lara
189
15k
Raft: Consensus for Rubyists
vanstee
140
7.1k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
KATA
mclloyd
32
14k
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を賢く扱ってい きましょう! (もっと情報が増えて欲しい…!)