0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初心者の壁⑪ dynamicは何でも出し入れ可能な便利な箱だと思っていたらFlutterとケンカになった話

0
Last updated at Posted at 2026-06-02

私:この100をdynamicに入れといて。後でスライドバーが取りに来るからよろしく。

Flutter:わかりました。

スライドバー:doubleくださいな。

Flutter:ちょっと見てきますね…そんなものはありません。

私:さっき100渡したでしょ。

Flutter:100はintです。

私:いや、勝手にintにしろなんて言ってないよ。

Flutter:ひどい…あなたが何も言わなかったから、私がちゃんと整理して入れておいたのに…

私:それなら、doubleちょうだいって言ったときもintをdoubleに変換してよ。

Flutter:それはできません。

私:はぁ???

Flutter:型安全ですので。


こうやって文字にしてみると
圧倒的に私が悪いですね。反省。

問題のコードはこれ

final dynamic initialValue;

この、initiate valueには、数字とbool型両方を入れることが想定されるので
dynamicにしていました。
そして、

values = {
  for (final p in widget.definition.touchParams)
    p.key: switch (p.uiType) {
      TouchUiType.slider =>
        p.initialValue ?? p.min ?? 0,

      _ =>
        p.initialValue,
    },
};

width: values['width']

入れた値を、スライドバーで使いたかったので
widthとして呼び出しています。
すると、こんなエラーが出ました。

type 'int' is not a subtype of type 'double?'

正直、何を言っているのか意味がわからないので
ChatGPTにエラーログをコピペして教えてもらいます。

すると、
表示されたエラーメッセージの
スタックトレースが指した箇所はここです、とのこと。

width: values['width'] ?? 100,
height: values['height'] ?? 80,

なるほど。確かにint入れてるっぽい。こうすればいいのかな。

width: values['width'] ?? 100.0,
height: values['height'] ?? 80.0,

しかし、これでは直りませんでした。

エラーの原因

結局、冒頭に書いたような
行き違いが原因でした。

私としては、dynamicに入れたんだから
intで入れたつもりはない。
しかも、表示はintにしたいと思っていたので
doubleで呼び出したつもりも全くない。

それなのに、
Flutterがdynamicに入れる時点で
勝手にintに変換し、
Sliderがdouble 前提で値を参照しに来たので
エラーになっていた、ということでした。
本当にわけが分かりませんでした。

解決方法はこれ

values = {
  for (final p in widget.definition.touchParams)
    p.key: switch (p.uiType) {
      TouchUiType.slider =>
        ((p.initialValue ?? p.min ?? 0) as num).toDouble(),

      _ =>
        p.initialValue,
    },
};

as numを挟んで
doubleで渡す。

さらにややこしい話

以前、ちょっとだけC++をかじったことがあるのですが
こういうのってエラーにならなかったんですよね。

int x = 100;
double y = x;

つまり、doubleってintの上位互換だと思っていたんです。

そして、実はFlutterでも
このコードはエラーになりません
Dartは int → double を許しているんです

じゃあ何がいけなかったのか。
今回のエラーの本質はこれでした。

dynamic x = 100;

double y = x;

コンパイル時に int だと分かっていると
doubleに変換してくれてエラーにならないけど
dynamicで入れていると
実行時にわざわざ中身を確認しに行くからエラーになる

なんだそれ…難しすぎるだろ…

まとめ

Dartは int → double を許しているが
dynamic や Map を経由すると型チェックのタイミングが変わり
実行時エラーになることがある

ということで
調べてみたら思ったよりややこしい話でした。

そもそも人間にとっては
100=100.0なわけで
この話が腑に落ちるまで、かなり時間がかかってしまいました。

それにしても、こんな真っ赤な画面を出して
かなりご立腹の様子。

そんなに怒らんでも…

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?