🪨

【Flutter】const と finalの違い!同じ定数じゃない??

2023/01/22に公開

Flutter(正確にはdart)には定数化するためにconstとfinalの2つがあります。

何となく違いはわかるが、正確にはハッキリわからないという方も多いかと思いますので具体的なコードも添えて説明します!

結論

const : アプリ内で絶対に値が変わらないものとして定義する
final : 実行時に定数化として保持しておきたいものを定義する

解説

具体的なコードを交えて解説と動きを見たいと思います!

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: '定数のサンプル'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  /// ↓ここから
  final finalConstant1 = "ファイナルな定数1";
  late final String finalConstant2;
  static const constConstant1 = "コンストな定数1";

  
  void initState() {
    super.initState();
    finalConstant2 = "ファイナルな定数2";
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(finalConstant1),
            Text(finalConstant2),
            const Text(constConstant1)
          ],
        ),
      ),
    );
  }
  /// ↑ここまで注目
}

上記の内容を見てみると

 final finalConstant1 = "ファイナルな定数1";
 late final String finalConstant2;
 static const constConstant1 = "コンストな定数1";

となっている部分があります。
ここでは各定数を初期化しています。
しかしfinalConstant2は値が入っていませんが、次の部分で値を設定しています。


void initState() {
  super.initState();
  finalConstant2 = "ファイナルな定数2";
}

これにより値を設定しています!

constにも同じように後から設定するような記述をしたらどうなる?

 final finalConstant1 = "ファイナルな定数1";
 late final String finalConstant2;
 static const constConstant1 = "コンストな定数1";
 static const constConstant2; /// ←この時点でコンパイルエラー

constの場合はあらかじめ値を設定していないとコンパイルエラーになってしまいます。

結果

constはコンパイル時から値を設定しているため定数である。
→ アプリ内では絶対に同じ値!!!
finalは実行時に値を設定しているしている。
→ アプリが実行された時に定数化し、再代入を不可能にしている。

補足説明

次のようにWidgetに対してconstを付けている場合と付けていない場合があります。

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Text(finalConstant1),
    Text(finalConstant2),
    const Text(constConstant1) /// 
  ],
 ),

この違いは、finalConstant1finalConstant2は実行時に値が設定されるため、constで定数化することが出来ず、対してconstConstant1自身がconstで定数化されており、その結果Wigetにもconstを付け定数化することが出来ます。

おまけ

Widgetにconstを付けることで、コンパイル時からの定数になるため、アプリ内での再レンダリングの処理が走る際に、その部分は再レンダリングされません。その結果、アプリのパフォーマンスの向上にも繋がります!

Discussion