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
8.5k
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
CSC307 Lecture 08
javiergs
PRO
0
330
ピグパーティにおけるMongoDB CommunityバージョンからAtlasへの移行事例
10969hotaka
0
130
CSC307 Lecture 09
javiergs
PRO
1
500
Temporalを取り巻く仕様を整理する
sajikix
0
110
CSC307 Lecture 14
javiergs
PRO
0
220
みんなのオブザーバビリティプラットフォームを作ってるんだがパフォーマンスがやばい #mackerelio #srenext
ne_sachirou
0
370
開発部に不満を持っていたCSがエンジニアにジョブチェンしてわかった「勝手に諦めない」ことの大切さ
sakuraikotone
28
16k
20240706_CDKConf
takuyay0ne
0
1.2k
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
160
Ruby メモリ管理 プログラミング
megmogmog1965
0
130
しくじり先生 Image Matching Challenge 2024 編
goosehaaan
0
810
SDCon2024: Enabling DevOps and Team Topologies thru architecture: architecting for fast flow
cer
PRO
0
780
Featured
See All Featured
Visualization
eitanlees
139
14k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
90
47k
Intergalactic Javascript Robots from Outer Space
tanoku
266
26k
How GitHub Uses GitHub to Build GitHub
holman
471
290k
Learning to Love Humans: Emotional Interface Design
aarron
269
39k
Building a Modern Day E-commerce SEO Strategy
aleyda
25
6.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
15
4.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
357
18k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
105
6.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
19k
Being A Developer After 40
akosma
72
580k
The Pragmatic Product Professional
lauravandoore
29
6.1k
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を賢く扱ってい きましょう! (もっと情報が増えて欲しい…!)