Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「🪦問題」から考えるGoのUnicodeサポート.pdf

8d6f91b92f4408a5ed8a4675f9034339?s=47 ARIGATOBANK
November 15, 2021

 「🪦問題」から考えるGoのUnicodeサポート.pdf

2021/11/13(土)に開催されたGo Conference 2021 Autumnに登壇させていただきました。
登壇テーマは、当社が開発時に遭遇した「🪦問題」から考えるGoのUnicodeサポートでした。
登壇資料とセッション概要を掲載します。

8d6f91b92f4408a5ed8a4675f9034339?s=128

ARIGATOBANK

November 15, 2021
Tweet

More Decks by ARIGATOBANK

Other Decks in Programming

Transcript

  1. 「🪦問題」から考えるGoのUnicodeサポート
 エンジニアリング部 大和屋貴仁


  2. strictly confidential Copyright ARIGATOBANK Inc. All Rights Reserved. 2 きっかけは前澤のお金贈り

    前澤はこの行動に 「大きな可能性」を感じた 最初はノリで始めた企画だった。 今まで寄付やチャリティーには積極的に関与する方だったが、なんとなく NPOや団体にお 金を出すだけでは人任せな気がしていた。 お年玉企画を通して、一人一人の挑戦や課題に耳を傾け、それに対して 100万円のお年 玉、つまり金銭的な支援ができるという、そんなダイレクトなお手伝いができることに大きな 可能性とやりがいを感じた。 今年2月以降は「困っている人や何かに挑戦したい人」に、資格取得を目指していたり社会 活動をしている、何かテーマを決めて挑戦をしたいなど、特定の目的をもってお金を必要と している人に絞ってお金贈りをしてきた。 詳細はこちらのnoteにて
  3. strictly confidential Copyright ARIGATOBANK Inc. All Rights Reserved. 株式会社ARIGATOBANKで解決したい課題
 何かに挑戦したい人が自ら声を上げて支援を受けられる場所がない

    富める人がもっと富み、貧しい人が取り残されているのが現状 災害時以外の日常的な個人寄付が圧倒的に少ない (アメリカは日本の40倍) お金の流れ、挑戦者への支援、寄付文化の醸成

  4. strictly confidential Copyright ARIGATOBANK Inc. All Rights Reserved. 4 何かに挑戦したくても、できない人が大勢いることを知っている

    少しのきっかけが挑戦に繋がることを知っている 挑戦によって人生が変わった人がいることを知っている これまで“32億円”のお金贈りを見てきたからこそ、できることがある なぜARIGATOBANKがやるのか?
  5. Strictly Confidential © ARIGATOBANK Inc. 5 - 個人間で簡単に寄付し合える CtoCの寄付プラットフォームサービス -

    寄付者は寄付プロジェクトを作成し、応募者を募集できる - 応募者はプロジェクトへ応募し、抽選を経て、寄付金の受け取りができる kifutownとは? <応募者> <寄付者>
  6. 背景的説明


  7. 背景:リリース2ヶ月前のある日
 テスト文字列でJSONパースエラーが発生
 どれが原因かわかります?
 {
 "id": "xxxxx-00001",
 "title": "夢のある方へ"
 "body": "💥💫😃🪦🪕🪔😄🦯💚💯😁🛑🥇🥓😆🪓💢😅🥙🥚"


    }

  8. 💥💫😃🪦🪕🪔😄🦯💚💯😁🛑🥇🥓😆🪓 💢😅🥙🥚 これと思った人は、ほとんど正解です。
 
 でも、全部では無いのです


  9. 💥💫😃🪦🪕🪔😄🦯💚💯😁🛑🥇🥓😆🪓 💢😅🥙🥚

  10. \U001faa6
 この文字列はなんでしょうか?


  11. Unicode 13.0 で追加された Emoji です


  12. Unicode 13.0 で追加された Emoji です
 知ってるようで知らないEmojiについて紹介します


  13. UnicodeとEmoji, UnicodeとOS, UnicodeとGo
 これを知らないと悩む話


  14. Emoji のお話


  15. Emoji History
 1999 Japanese Emoji
 2008 Gmail/iPhone
 2010 Unicode 6.0.0

    Emoji
 EmojiをUnicodeに収録するProposalが提案され、採択された。

  16. Proposal for Encoding Emoji Symbols
 AppleとGoogleの6人による共同提案
 
 ドコモ、KDDI、ソフトバンクが使ってる
 Shift-JISの拡張、ISO-2022-JPで
 エンコードされたEmojiへの対応


  17. Unicode® Technical Standard #51 UNICODE EMOJI 
 https://www.unicode.org/reports/tr51/#Versioning 
 Unicodeのアップデート時にEmojiもアップデートされる


    Emoji 13.0で新たに117個追加

  18. Emoji はUnicodeで定義されて、
 各社のプロダクトは定義されるたびに追随して、
 サポートをしていく世界線


  19. Unicodeのアップデート後、
 4〜8ヶ月後にiOSでサポートされて、利用ができるようになる


  20. iOSでサポートされて、3〜6ヶ月程度でGoでサポートされる


  21. Emoji
 iOS
 Golang
 2019/10/21
 2019/10/28
 Emoji 12.0/12.1 
 2020/02/25
 2020/03/10


    Emoji 13.0
 2020/11/05
 2021/02/16
 Emoji 13.1
 2021/04/26
 2020/09/15
 7日
 120日
 240日
 223日
 103日
 190日

  22. Emoji 13.0
 iOS
 2020-03-10
 14.2
 2020-11-05
 1.16
 2021-02-16
 103日後


  23. Goのバージョン毎の結果差異


  24. Go のバージョンによって挙動が変わる
 fmt.Printf("%q", "🪦" )


  25. Go 1.15
 Go 1.16
 fmt.Printf("%q", "🪦")
 \U001faa6
 Go がサポートしているユニコードの違いによる


  26. 遭遇した箇所


  27. データストアにSpanner
 言語にGolangで、Spanner SDK for Goを使用


  28. spanner.NullString
 Spanner SDK for Goで提供されているNullの可能性がある場合のStringデータ型
 // MarshalJSON implements json.Marshaler.MarshalJSON for

    NullString. func (n NullString) MarshalJSON() ([]byte, error) { if n.Valid { return []byte(fmt.Sprintf("%q", n.StringVal)), nil } return jsonNullBytes, nil }
 🪦を含んだ文字列で遭遇した問題箇所

  29. fmt.Sprintf
 お馴染みの指定したフォーマットで文字列を返す関数
 func (f *fmt) fmtQ(s string) { s =

    f.truncateString(s) if f.sharp && strconv.CanBackquote(s) { f.padString("`" + s + "`") return } buf := f.intbuf[:0] if f.plus { f.pad(strconv.AppendQuoteToASCII(buf, s)) } else { f.pad(strconv.AppendQuote(buf, s)) } }

  30. strconv.AppendQuote
 func appendQuotedRuneWith(buf []byte, r rune, quote byte, ASCIIonly, graphicOnly

    bool) []byte { buf = append(buf, quote) if !utf8.ValidRune(r) { r = utf8.RuneError } buf = appendEscapedRune(buf, r, quote, ASCIIonly, graphicOnly)
  31. strconv.AppendQuote
 func appendEscapedRune (buf []byte, r rune, quote byte, ASCIIonly,

    graphicOnly bool) []byte { var runeTmp [utf8.UTFMax]byte if r == rune(quote) || r == '\\' { // always backslashed buf = append(buf, '\\') buf = append(buf, byte(r)) return buf } if ASCIIonly { if r < utf8.RuneSelf && IsPrint(r) { buf = append(buf, byte(r)) return buf } } else if IsPrint(r) || graphicOnly && isInGraphicList (r) {
  32. strconv.IsPrint
 GoでPrint可能かどうかを確認する
 func IsPrint(r rune) bool { // Fast check

    for Latin-1 if r <= 0xFF {   省略 } if 0 <= r && r < 1<<16 { rr, isPrint, isNotPrint := uint16(r), isPrint16, isNotPrint16
  33. isPrint16


  34. unicode: upgrade to Unicode 13.0.0
 adds 5,930 new characters
 including

    55 new Emoji.
 GoでのUnicodeは
 対象範囲を指定している。
 この対応がされないと
 新しい文字を認識できない。

  35. まとめ


  36. Unicode 13.0 で追加された Emoji です


  37. ユーザーから任意の文字列を受け付ける部 分では、string型を使用する
 iOS/Androidがサポートすると
 ユーザーが入力してくるようになる
 Golangでのサポートまで処理できなくなるので
 Unicodeに依存した実装を回避するのがリーズナブル


  38. こぼれ話


  39. Emoji のOS依存のお話
 Emojiは、各OSのサポートに依存している。
 例えば、今日のセッションタイトルをWindowsでは
 
 「□問題」から考えるGoのUnicodeサポート」
 
 と表示されたそうです。
 人事から「□問題」ってなんですか?と聞かれました。


  40. 参考:Emojiへの各サービスの絵文字マスター取り組み
 OS依存にしないために各自で独自のUnicodeマッピングを
 実装している例も。


  41. None