旧サイトから記事の移行中です

関数を実行するときの ( ){ } とか => ってなに?

Dartで関数を実行するとき、( ){ }( )=>の使い分けできていますか?

どちらも関数を実行するときに使う記号ですが、意味がわかっていないと()=>{}とか書いてエラーになって、なんとなく解決できたとしても、モヤモヤしてしまう。

そのモヤモヤを解決するカギは「関数の名前」と「関数に渡す値(引数)」です。
(){}()=>の使い方をまとめました。

動作確認バージョン
  • Flutter : 3.24.4
  • Dart : 3.5.4
目次

はじめに:TextField() の onSubmitted: で関数を実行します

今回の例では、「Flutterで、テキストフィールドの入力値を画面に表示する」という処理を、関数として実行しようと思います。

文字入力にはTextField()を使い、入力が確定したときのイベントとしてonSubmitted:オプションを使います。

TextFieldに入力した値をスマホ画面に表示する際の、onSubmittedイベントに指定する関数を(){}で書いた例。
onSubmitted: は、スマホ右下のマークを押したときに発動する。
または、エミュレータ使用時はエンターキーを押したときに発動。

( ){ }は「(引数) {実行内容}」

(){}で関数を書くとき、()の中に書いた変数は{}の中だけで使える。

onSubmitted:直後の( )の中にあるvalueは、その後ろの{ }の中だけで使える変数です。

この変数には、TextField()の場合では、入力欄に入力した文字列値が入っています。
変数名は自分で自由に決めます。

その次の{ }の中には、valueという引数を受けて実行する処理を書きます。
このコードの例では、setStateだけしか実行していませんが、setStateの前後にも複数の命令を書いて実行することができます。

(){}で関数を実行する際、{}の中には複数の命令文を書くことができる。 {}内のsetState()の次に、print()の命令を入れてもエラーなく動作している例。
{ }の中には2行以上の命令文を書ける
  • (...){ }の中だけで使える変数(名前は任意)を...に書く。
  • {...}( )内の変数を使って実行する処理を...に書く。複数の命令文を書ける。

ところで、( ){ }という書き方は、関数っぽく見えないかもしれませんが、これも関数です。

今回のDartコードの例では、引数を受けて画面表示する処理は、このTextFieldの中でだけ実行すればよいことで、処理内容をわざわざ別行立てにして保存しておくほどの必要がありません。

その場所でのみ実行される処理で、他の場所で使うことがないのです。

そういう場合は、引数と処理のみを記述する「( ){ }」を使います。

これは、引数と処理内容だけしか記述しない「名前のない関数」なので、「無名関数」とか「匿名関数」などと言います。
英語でいうと「Anonymous Function」です。

( )=>は「(引数) => 1行の実行文」

一方の( )=>...の場合、=>の後ろに書くのは「実行文1行」だけです。

この書き方は、=>が矢印に似ているので「アロー関数」と言います。

アロー関数は、名前のない「無名関数」形式での実行もできますが、名前付きで作成した関数(メソッド)の実行もできます。

「無名関数」として実行する場合

( )=>...( )は、( ){ }の場合と同じで、( )内に「引数」を入れます。

アロー関数=>で、無名関数を実行している例。
=>の後ろに書ける命令文は「1つだけ」
  • (...)=>の後ろの命令文の中だけで使える変数(名前は任意)を...に書く
  • =>...( )内の変数を使って実行する命令文(式)を...に書く

前述の( ){ }で実行した処理は、setStateのひとつの命令だけなので、( )=>で書き換えることもできます。

アロー関数=>で、無名関数を実行している例。
( ){ }( )=>で書き換える

setStateの中で実行する命令文は、1行ごとに改行して記述することが多いので、複数の命令文を書いているように見えますが、これはコードを見やすくするために改行しているだけです。

なので、onSubmitted:( )=>で実行しているのはsetStateだけですから=>で記述することができるわけです。

試しに、setStateの中のviewText = value;の次に、viewText = '$viewText が入力されました';という1文を追加して実行しても、エラーなく機能します。

アロー関数=>を使って関数を書くときは、命令文は1つしか書けない。2つ以上書いてエラーになっている例。
アロー関数では2つ以上の命令は書けない

名前付きの関数を実行する場合

名前をつけて作成した関数を呼び出す場合は、1行の命令として書けるので、( )=>を使います。

下記では、メソッドとして作成したupdateScreenへ引数を渡して実行しています。

メソッドとして作成しておけば、メソッド内で実行する命令文の数に制限がないので、複雑な処理も実行できるし、他の場所から呼び出して使うこともできます。

アロー関数=>でメソッドを実行している例。
メソッドの中なら複雑な処理もOK

if文はNG、三項演算子はOK

( )=>では、複数の命令を書くことはできませんから、if文も書けません。

でも、三項演算子は1つの命令文なので書くことができます。

setStateの実行は1行が長くなるので、メソッド作成した方が見やすいとは思いますが、一つの例としてあげておきます。

アロー関数=>で三項演算子を実行している例。
updateScreenifを、三項演算子に書き換え

Dartファイルのサンプル

以下は、今回のサンプルで作成した、main.dartとhome_screen.dartです。

いちよ、main.dartがコレ
13行目で、HomeScreen()を呼んでいます。

import 'package:flutter/material.dart';
import 'screens/home_screen.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Child to Parent Try',
      home: HomeScreen(),
    );
  }
}

( ){ }の場合

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<HomeScreen> {
  String viewText = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('入力したテキスト :   $viewText'),
            TextField(
              onSubmitted: (value) {
                setState(() {
                  viewText = value;
                });
                print('入力値:$viewText');
              },
            )
          ],
        ),
      ),
    );
  }
}

( )=>...で無名関数を実行する場合

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<HomeScreen> {
  String viewText = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('入力したテキスト :   $viewText'),
            TextField(
              onSubmitted: (value) => setState(() {
                viewText = value;
                viewText = '$viewText が入力されました';
              }),
            )
          ],
        ),
      ),
    );
  }
}

( )=>...で三項演算子を実行する場合

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<HomeScreen> {
  String viewText = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('入力したテキスト :   $viewText'),
            TextField(
              onSubmitted: (value) => value == '1'
                  ? setState(() {viewText = value;})
                  : setState(() {viewText = '1以外';}),
            )
          ],
        ),
      ),
    );
  }
}

( )=>...でメソッドを実行する場合

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<HomeScreen> {
  String viewText = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('入力したテキスト :   $viewText'),
            TextField(
              onSubmitted: (value) => updateScreen(value),
            )
          ],
        ),
      ),
    );
  }

  updateScreen(String inputtedText) {
    if(inputtedText == '1') {
      viewText = inputtedText;
    }
    else{
      viewText = '1以外';
    }
    setState(() {
    });
  }
}
よかったらシェアしてね!
  • URLをコピーしました!
目次