スタッフブログ

STAFF BLOG

アプリ開発日誌

2021.07.16

Flutter開発のためのDart入門(2)関数

Dart_programming_language_logo

関数

前回のDart入門(1)の投稿に続き、今回もDartについて解説していきます。

今回は関数について解説します。

関数の定義

基本的な関数の定義は次のようになります。

戻り値の型 関数名 (仮引数の型 仮引数名) {
 return 戻り値;
}

関数の呼び出しは次のようになります。

関数名 (実引数);

簡単な関数の実装例は次のようなコードになります。

String sayHello(String name) {
  return 'Hello ${name}';
}

void main() {
  var greeting = sayHello('Satoshi');
  print(greeting);
}

実行結果

Hello Satoshi

式を1つだけ含む関数の場合は、returnの代わりにアロー演算子=>を使い簡潔に記述できます。

String sayHello(String name) => 'Hello ${name}';

void main() {
  var greeting = sayHello('Satoshi');
  print(greeting);
}

実行結果

Hello Satoshi

関数のパラメータ

関数は任意の数のパラメータ(仮引数)を持つ事ができます。
仮引数が複数ある場合、カンマ,で区切ります。

int area(int height, int width) {
  return height * width;
}

void main() {
  var result = area(2, 3);
  print(result);
}

実行結果

6

名前付きパラメータ

関数を定義する際に仮引数を{}で囲むと、呼び出し側で実引数に名前を付けられます。

戻り値の型 関数名 ({仮引数の型: 仮引数名}) {
  return 戻り値;
}

関数の呼び出しは次のようになります。

関数名 (仮引数名: 実引数);

名前付きパラメータはオプションで省略可能のため、値がnullになる可能性があります。

※Dart 2.12 以降で null-safe(null 安全)を選択した場合、仮引数の型名に?クエスチョンマークを付けないとコンパイルエラーとなります。
下記のコードはnullチェックをif文でおこなっています。
if文は今後の投稿で解説します。

String say(String from, String msg, {String? device}) {
  var result = '$fromからのメッセージ 「$msg」';
  if (device != null) {
    result = '$result 〜$deviceから';
  }
  return result;
}
実行結果
void main() {
  var message = say('タロー', '元気ですか?');
  print(message);
  message = say('タロー', '元気ですか?', device: 'スマートフォン');
  print(message);
}
タローからのメッセージ 「元気ですか?」
タローからのメッセージ 「元気ですか?」 〜スマートフォンから

オプショナルパラメータ

仮引数を[]で包むと、オプションのパラメータになります。

String say(String from, String msg, [String? device]) {
  var result = '$fromからのメッセージ 「$msg」';
  if (device != null) {
    result = '$result 〜$deviceから';
  }
  return result;
}

void main() {
  var message = say('タロー', '元気ですか?');
  print(message);
  message = say('タロー', '元気ですか?', 'スマートフォン');
  print(message);
}

実行結果

タローからのメッセージ 「元気ですか?」
タローからのメッセージ 「元気ですか?」 〜スマートフォンから

名前付きパラメータは省略可能ですが、@requiredというアノテーションを付けると、仮引数に値を指定するのが必須になります。
@requiredを使用するには下記のパッケージをインポートします。
import 'package:meta/meta.dart';

import 'package:meta/meta.dart';

String say({@required String? from, @required String? msg, String? device}) {
  var result = '$fromからのメッセージ 「$msg」';
  if (device != null) {
    result = '$result 〜$deviceから';
  }
  return result;
}

void main() {
  var message = say(from: 'タロー', msg: '元気ですか?', device: 'スマートフォン');
  print(message);
  message = say(from: 'タロー', msg: '元気ですか?');
  print(message);
  message = say(from: 'タロー');  // 引数'msg'を省略
  print(message);
}

実行結果

タローからのメッセージ 「元気ですか?」 〜スマートフォンから
タローからのメッセージ 「元気ですか?」
タローからのメッセージ 「null」
// line 16 • The parameter 'msg' is required.

デフォルトパラメータ

=を使用して、名前付きパラメータとオプショナルパラメータの両方のデフォルト値を定義することができます。

String say(String from, String msg, [String? device = 'スマートフォン']) {
  var result = '$fromからのメッセージ 「$msg」';
  if (device != null) {
    result = '$result 〜$deviceから';
  }
  return result;
}

void main() {
  var message = say('タロー', '元気ですか?');
  print(message);
}

実行結果

タローからのメッセージ 「元気ですか?」 〜スマートフォンから

main関数

main()関数は一つだけ存在できます。

main()の前にあるvoidは関数の戻り値の型です。

main()関数やprint()関数など、値を返さない関数の場合、この戻り値の型を指定します。

匿名関数

関数には関数名がありますが、関数名の無い関数もあります。
これを匿名関数(無名関数)と言います。
Dartでは関数を変数に代入したり、別の関数のパラメータとして渡すことができます。
無名関数の定義は次のようになります。

(仮引数の型 仮引数名) {
  return 戻り値;
}

コードは次のようになります。

void main() {
  var greeting = (name) {
    return 'Hello, ${name}!';
  };
  print(greeting('Dart'));
}

実行結果

Hello, Dart!

関数の型はFunction型です。

void main() {
  var greeting = (name) {
    return 'Hello, ${name}!';
  };
  print(greeting('Dart'));
  print(greeting is Function);
}

実行結果

Hello, Dart! 
true

次のコードはパラメータitemを持つ無名関数を定義しています。
この関数は、リスト内の各項目に対して呼び出され、指定されたインデックスの値を含む文字列を表示します。

void main() {
  var list = ['apples', 'bananas', 'oranges'];
  list.forEach((item) {
    print('${list.indexOf(item)}: $item');
  });
}

実行結果

0: apples
1: bananas
2: oranges

スコープ

Dartはスコープ(可視範囲)が有効な言語です。
スコープとは、ある変数や関数などの名前(識別子)を参照できる範囲のことです。
通常、変数や関数が定義されたスコープの外側からは、それらの名前を用いるだけでは参照できません。
このときこれらの変数や関数は「スコープ外」である、あるいは「見えない」といわれます。
通例、入れ子になったスコープ階層ごとに同じ名前の識別子が出現したとき、より内側のスコープに属する識別子のほうが優先的に参照されます。

void main() {
  var x = 100;
  print(x); // 100

  {
    var x = 200;
    print(x); // 200
    var y = 300;
  }

  print(x); //100

  // コメントを外すとコンパイルエラー
  // print(y);
}

実行結果

100
200 
100

静的クロージャ (Lexical closures)

クロージャはStringやintを変数に保存するように、関数オブジェクトとして保存します。

次のコードは変数add2に、実引数に2を渡したクロージャ(int i) => addBy + i;を代入しています。

実際には仮引数addBy2が渡されるので、(int i) => 2 + i;となります。

この時点ではmakeAdder()関数は実行されません。

この後、add2(3)を実行すると仮引数i3が渡されるので(int 3) => 2 + 3;が実行されて5になります。

この後、add4変数にmakeAdder(4)を代入しても、変数add2にはmakeAdder(2)が保持され続けます。

Function makeAdder(int addBy) {
  return (int i) => addBy + i;
}

void main() {
  var add2 = makeAdder(2);
  var add4 = makeAdder(4);

  print(add2(3) == 5);
  print(add4(3) == 7);
}

実行結果

true 
true

次回は演算子について投稿する予定です。

ライタープロフィール

【N】
Webエンジニアの経験を経て、アプリエンジニアとしてEDAに入社。
Flutter開発導入のファシリテーターとして、勉強会などを担当している。

BACK

お問合せ

イーディーエーに興味をお持ちいただいて
ありがとうございます!
スマホアプリに関するご相談、
お見積りや弊社へのご質問など、
お気軽にお問い合わせください。
担当者より折り返しご連絡させていただきます。

    お名前必須
    会社名
    メールアドレス必須
    電話番号必須
    お問合わせ種別必須
    お問合わせ内容必須

    アンケートにご協力ください。
    弊社サイトへはどのようにしてアクセスされましたか?

    個人情報のお取扱いに関する同意事項

    1.事業者の氏名又は名称

    株式会社イーディーエー

    2.個人情報保護管理者の氏名又は職名、所属及び連絡先

    個人情報保護管理者 小宮 保人
    Mail:[email protected]

    3.取得した個人情報の利用目的

    当フォームで取得した個人情報は、お問い合わせに関する回答のために利用し、目的外利用はいたしません。

    4.弊社が取得した個人情報の第三者への委託、提供について

    弊社は、ご本人に関する情報をご本人の同意なしに第三者に委託または提供することはありません。

    5.個人情報保護のための安全管理

    弊社は、ご本人の個人情報を保護するための規程類を定め、従業者全員に周知・徹底と啓発・教育を図るとともに、その遵守状況の監査を定期的に実施いたします。
    また、ご本人の個人情報を保護するために必要な安全管理措置の維持・向上に努めてまいります。

    6.個人情報の開示・訂正・利用停止等の手続

    ご本人が、弊社が保有するご自身の個人情報の、利用目的の通知、開示、内容の訂正、追加又は削除、利用の停止、消去及び第三者への提供の停止を求める場合には、下記に連絡を頂くことで、対応致します。

    株式会社イーディーエー 個人情報お問合せ窓口
    〒106-0032 東京都港区六本木7丁目14番23 ラウンドクロス六本木4F
    TEL:03-5422-7524 FAX:03-5422-7534
    Mail:[email protected]

    7.ご提供いただく情報の任意性

    個人情報のご提供は任意ですが、同意を頂けない場合には、第3項にあります利用目的が達成できない事をご了承いただくこととなります。

    8.弊社Webサイトの運営について

    弊社サイトでは、ご本人が弊社Webサイトを再度訪問されたときなどに、より便利に閲覧して頂けるよう「クッキー(Cookie)」という技術を使用することがあります。これは、ご本人のコンピュータが弊社Webサイトのどのページに訪れたかを記録しますが、ご本人が弊社Webサイトにおいてご自身の個人情報を入力されない限りご本人ご自身を特定、識別することはできません。
    クッキーの使用を希望されない場合は、ご本人のブラウザの設定を変更することにより、クッキーの使用を拒否することができます。その場合、一部または全部のサービスがご利用できなくなることがあります。