発表資料 - Gophers Meetup 2026

>100 Views

October 08, 26

スライド概要

https://tokium.connpass.com/event/405908/

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

Jev-goから学ぶ 型安全ってなんだろう haruki

2.

自己紹介 haruki モビルス株式会社 2026新卒 Go conference 2026 初参加

3.

Jev 先月登場して話題になった Jev 早速使うために SDK について調べてみました

4.

Jev SDK Python JavaScript / TypeScript Go はない

5.

ないなら作る! ということで Jev-go を作ってみよう...

6.

もうありました。 kataras/jev valksor/typesafe-sdk-go FelineStateMachine/typesafe-go shanehull/go-jev mattn/go-jev waygatetech/jev-go tgallice/jev-go anilsenay/jev fgn/jevgo havlan/jev-go

7.

めっちゃあった それぞれの特徴を比較してみました

8.

比較 1. バージョン 2. 型の扱い

9.

1. バージョン go.mod の宣言と、実際に必要なバージョン

10.

go.mod の宣言 各ライブラリが宣言している Go のバージョン 1.27 kataras / Feline / mattn 1.25 1.26 tgallice / fgn / valksor / shanehull / waygatetech 1.22 anilsenay / havlan 〜

11.

実際に必要なバージョン 使っている機能から逆算すると 1.27 kataras / Feline(generic methods、json/v2) 1.22〜 tgallice / fgn / valksor / anilsenay(slog、rand/v2) 1.24 ≤ 1.21 mattn / shanehull / waygatetech / havlan

12.

go.mod の宣言とのずれ 宣言どおり必要なのは 10 個中 3 個だけ 一致:kataras / Feline / anilsenay 残り 7 個は、宣言が実際より新しい

13.

2. 型の扱い 質問ごとに違う型の「答え」をどう返すか

14.

3つの作戦 答えは Noul / Choice / Score の3種類 A 1つの構造体に全部入れる B interface と型アサーション C ジェネリクス

15.

作戦A:1つの構造体 3種類の答えのフィールドを並べる(mattn/go-jev) type Answer struct { Type string; Noul float64; Choice string; ... }

16.

作戦A:1つの構造体 いちばん分かりやすい。でも… と直接読める。型アサーション不要 Noul の答えで a.Choice を読んでも空文字が返るだけ → 間違いに気づけない a.Choice

17.

作戦B:interface と型アサーション 型アサーションをメソッドの中に隠す(kataras/jev など) func (r *Response) Choice(name string) (ChoiceAnswer, bool) { a, ok := r.Answers[name].(ChoiceAnswer) return a, ok }

18.

作戦B:interface と型アサーション いちばん多く採用されている作戦 ans, ok := res.Choice("team") 型が違えば ok == false が返る → 実行時に気づける と書くだけ

19.

作戦B:interface と型アサーション kataras/jev のひと工夫 type Question interface { isQuestion() } 小文字のメソッドはパッケージの外から実装できない → ライブラリが定義した型しか入らない

20.

作戦C:ジェネリクス 型を引数のように受け取れる(Go 1.18〜) func First[T any](xs []T) T { return xs[0] } First([]int{1, 2}) // int First([]string{"a"}) // string が返る が返る

21.

作戦C:ジェネリクス 答えの型を先に用意しておく(tgallice/jev-go) team := jev.Ask(req, "team", jev.Choice(...)) res, _ := client.Evaluate(ctx, req) a, _ := team.Answer(res) // a ChoiceAnswer は 型

22.

作戦C:ジェネリクス 型アサーションそのものが不要になる 作戦B:実行時に「ChoiceAnswer のはず」と確かめる 作戦C:コンパイル時点で答えの型が決まっている → 間違えたら実行前にコンパイルエラー

23.

作戦採用状況 型を間違えたとき、いつ気づけるか A 気づかない B 実行時 C コンパイル時 mattn / waygatetech(havlan は実行時) shanehull / valksor / fgn / kataras / Feline tgallice / anilsenay

24.

まとめ 同じ目的でも、型/バージョンの考え方で 実装が大きく異なる

25.

おまけ Jev についてブログ書きました Ask me anything情報あるよ