初めてのプログラミング学習用【Dart(Flutter)】
「プログラミングを初めて勉強するなら、まずはここから知っていこう!」という内容になっています。
たくさん説明がありますが、暗記は不要ですので気楽に読んでください。
忘れたら何度でも見返せばOKです。プログラミングはカンニングOKなんです。
また、後半に行くほどややこしくなりますが、1発で全て理解するのは天才じゃないと難しいと思います。
何度も繰り返し使っていると、簡単に感じてきますので、今はなんとなくの理解でOKです。
上手く進められない箇所があれば、コメントを残してくだされば、できる限り回答いたします。
お気軽にご質問ください。
では、学習に入りましょう!
プログラミングとは?
コンピュータに命令することをプログラミングといいます。
コンピュータは自分で考えることができないため、一つ一つの動きを順番に書き出す必要があります。
例えばロボットを歩かせたい場合、
「右足を上げる→右足を前に出す→右足を下ろす」
みたいな命令に従ってコンピュータが動きます。
コンピュータは日本語で命令しても理解できないので、コンピュータが理解できる言語で命令する必要があります。それをプログラミング言語と言います。
プログラミング言語はたくさん種類がありますが、このnoteではDartというプログラミング言語を使用します。
簡単なコードを動かしてみよう
実際に簡単なコードを書きながら読み進めてほしいので、DartPadというサイトを使っていただきます。
▶︎ここをクリックしてください
↓このようなサイトが開きます。これがDartPadです。ここにいろんなコードを書いて、実際に動かしていきます。
DartPadの左側のコードを全て消して、下記のコードを書いてください。
void main() {
print("Hello World");
}
書けたら「▶︎ Run」と書かれているボタンをクリックしてください。
↓のように右上に「Hello World」と表示されていればOKです。
[コードの解説]
Dartのコードを実行するとき、main関数の中に書かれたコードが実行されます。{ }の間に書かれたコードが上から順番に実行されます。下記がmain関数です。↓
void main() { // ここから
} // ここまでの間がmain関数の中です
Console(DartPadの右上)という場所にデータを表示するためのprint関数というコードがあります。( )の間に書かれたデータが表示されます。下記がprint関数です。↓
print("Hello World"); // ()の間に書かれた「Hello World」がConsoleに表示されます。
変数
変数とは
プログラミングでの変数は「値を入れておく箱」のようなものです。
数学のxやyみたいな変数と同じような意味です。
例えば、下記のようなコードがあったとします。
int a = 1;
このコードは、下のようなことをしています。
下記のコードをDartPadに書いてください。
void main() {
int a = 1; // 変数aの中に1を入れる
print(a); // 変数aの中身をConsoleに表示する
}
Runをクリックしてコードを実行すると、右側のConsoleに「1」と表示されます。変数「a」の中に「1」が入っていることが分かります。
変数の中には一つしかデータを入れられません。
下記のコードをDartPadに書いて実行してみてください。
void main() {
int a = 1; // 変数aの中に1を入れる
a = 2; // 変数aの中に2を入れる
print(a); // 変数aの中身をConsoleに表示する
}
右側のConsoleに「2」と表示されます。変数「a」の中に「1」が「2」に入れ替わっています。
上の例では変数に整数を入れていますが、整数以外にも少数や文字など、いろんな変数があります。
変数は中に入れるデータの形によって、型があります。
ここからはいろんな型の変数を紹介していきます。
int型
整数を入れる箱です。
↓例
int number = 100;
int(整数の箱)に
numberという名前を付けて
「100」を入れています。
double型
小数を入れる箱です。
↓例
double number = 1.5;
double(小数の箱)に
numberという名前を付けて
「1.5」を入れています。
String型
文字列を入れる箱です。
↓例
String greeting = 'Hello World';
String(文字列の箱)に
greetingという名前を付けて
「Hello World」を入れています。
文字列は「'」か「"」で挟む必要があります。
boolean型
プログラムの中で正しいor間違いを判定することがあります。
↓のコードをDartPadに入力して、Runで実行してみてください。
void main() {
print(1 == 1);
}
DartPadの右側のConsoleに「true」と表示されます。
「true」は正しいという意味です。
上のコードの「==」は、「==」の右側と左側が同じかどうかを判定するものです。
この場合は、右も左も「1」で同じなので、正しいという意味の「true」となります。
今度は下記のコードをDartPadで実行してみてください。
void main() {
print(1 == 2);
}
Consoleに「false」と表示されます。
「false」は間違いという意味です。
「1」と「2」は同じではないので、「false」が表示されます。
この「true」と「false」を日本語で「真偽値」と言います。
そして、「true」か「false」を入れる箱を「boolean型」と言います。
↓例
boolean result = true;
boolean(真偽値の箱)に
resultという名前を付けて
「true」を入れています。
List型
実は、ここまでで解説した型の変数では、複数のデータを入れることができません。
List型なら複数のデータを一つの変数にいれることができます。
複数のデータが入っている変数を日本語では配列といいます。
↓イメージ
↓コードにするとこうなります。
List fruit = ["りんご", "みかん", "いちご"];
List型の中身には左から順番に、0, 1, 2, …と番号がついています。
上の例では、0→りんご、1→みかん、2→いちご
となります。
List型の変数から一つのデータを取り出したい時、下のような書き方をします。
変数名[番号]
下のコードをDartPadに書いて実行してみてください。Consoleに「りんご」と表示されます。
void main() {
List fruit = ["りんご", "みかん", "いちご"];
print(fruit[0]);
}
「0」を「1」や「2」に書き換えて実行して、「みかん」や「いちご」も表示させてみましょう。
Map型
Map型もList型と同じように複数のデータを扱うことができます。
List型と違う点
List型は一つ一つに番号がついています。
Map型は番号ではなく、一つ一つ名前を付けていきます。
↓イメージ
↓コードにするとこうなります。
「apple」「orange」「strawberry」は一つ一つの箱の名前で、キーといいます。
「りんご」「みかん」「いちご」は、その中身のデータです。
Map型の変数から一つのデータを取り出したい時、下のような書き方をします。
変数名["キー"]
下のコードをDartPadに書いて実行してみてください。Consoleに「りんご」と表示されます。
void main() {
Map fruit = {"apple": "りんご", "orange": "みかん", "strawberry": "いちご"};
print(fruit["apple"]);
}
「apple」を「orange」や「strawberry」に書き換えて実行して、「みかん」や「いちご」も表示させてみましょう。
演算子
演算子とは
計算をするとき、「+」「-」「×」「÷」といった記号を使いますよね?
これらの記号のことを演算子といいます。
プログラミングでも変数のデータを足したり引いたり色々します。
演算子もたくさん種類があるので、一つ一つ解説していきます。
最初にもお伝えしましたが、覚えなくて大丈夫ですからね。
忘れたら何度でも見返せばいいだけなので。
算術演算子
算術演算子は簡単にいうと、「+」「-」「×」「÷」のような計算するための演算子です。
下記のコードをDartPadに書いて実行してみてください。
計算結果がConsoleに表示されます。
void main() {
int num = 10; // 変数numに10を入れる
print(num + 1); //足し算
print(num - 1); //引き算
print(num * 2); //掛け算
print(num / 2); //割り算
print(num % 3); //余り
}
「+」「-」はそのまま
「×」は「*」
「÷」は「/」
を使います。
最後の「num % 3」は「10を3で割ったときの余り」を計算しています。
比較演算子
比較演算子は2つのデータを比較する演算子です。
比較した結果、true(正しい)かfalse(間違い)か判定されます。
下記のコードをDartPadに書いて実行してみてください。
計算結果がConsoleに表示されます。
void main() {
int num = 10;
print(num > 1); // numが1より大きいならtrue、違う時はfalse
print(num >= 1); // numが1以上ならtrue、違う時はfalse
print(num < 1); // numが1より小さいならtrue、違う時はfalse
print(num <= 1); // numが1以下ならtrue、違う時はfalse
print(num == 1); // numが1と同じならtrue、違う時はfalse
print(num != 1); // numが1ではないならtrue、違う時はfalse
}
変数「num」に入れた10を書き変えて、Consoleの表示が変わるかどうか試してみましょう。
条件分岐
条件分岐とは
条件によって実行するコードを変えることをいいます。
日常生活に例えると、
「雨が降っていたら電車で行く、雨が降っていなかったら自転車で行く」
みたいなイメージです。
if文
下記のような書き方をします。
if(条件式){
条件式がtrueの時の処理...
}
下記のコードをDartPadに書いて実行してみてください。
計算結果がConsoleに表示されます。
void main() {
int num = 10;
if (num >= 5) {
print('5以上');
}
}
上のコードは変数numが5以上の時は「5以上」と表示します。
今度は下記のコードをDartPadに書いて実行してみてください。
void main() {
int num = 3;
if (num >= 5) {
print('5以上');
}
}
Consoleに何も表示されません。
上のコードは変数numに3が入っていて、5以上ではありません。
そのため、「print('5以上');」のコードが実行されませんでした。
if...else文
下記のような書き方をします。
if(条件式){
条件式がtrueの時の処理...
}
else{
条件式がfalseの時の処理...
}
下記のコードをDartPadに書いて実行してみてください。
計算結果がConsoleに表示されます。
void main() {
int num = 6;
if (num >= 5) {
print('5以上');
}
else {
print('5未満');
}
}
変数numは6なので「print('5以上');」が実行されて、「5以上」と表示されます。
今度は下記のコードをDartPadに書いて実行してみてください。
void main() {
int num = 4;
if (num >= 5) {
print('5以上');
}
else {
print('5未満');
}
}
変数numは4なので「print('5未満');」が実行されて、「5未満」と表示されます。
else if
下記のような書き方をします。
if(条件式A){
条件式Aがtrueの時の処理...
}
else if(条件式B){
条件式Bがtrueの時の処理...
}
else if(条件式C){
条件式Cがtrueの時の処理...
}
else{
条件式A,条件式B,条件式Cが全てfalseの時の処理...
}
下記のコードをDartPadに書いて実行してみてください。
void main() {
int num = 3;
if (num >= 10) {
print('10以上');
} else if (num >= 5) {
print('5以上');
} else if (num >= 0) {
print('0以上');
}
else {
print('0より下');
}
}
「num >= 10」がfalse
「num >= 5」もfalse
「num >= 0」はtrueなので、「print('0以上');」が実行されて、「0以上」と表示されます。
関数
ここから難しさが上がってきます。
最初は何となくでいいので、目を通していただけたらと思います。
アプリを作る時に何度も出てくると思うので、その度に復習していただければ、徐々に理解が進むかと思います。
関数とは
処理をまとめたプログラムの部品のようなものです。
と言われてもよく分からないと思うので、まずは下記のコードを見てください。
void main() {
print('今日は');
print('学校で勉強');
print('放課後は部活');
print('ーーーー');
print('明日も');
print('学校で勉強');
print('放課後は部活');
print('ーーーー');
print('明後日は');
print('休みなので一日中寝てる');
}
今日と明日の内容が同じなので、関数にまとめます。
下記のように書き換えることができます。
void main() {
print('今日は');
heijitu();
print('ーーーー');
print('明日も');
heijitu();
print('ーーーー');
print('明後日は');
print('休みなので一日中寝てる');
}
void heijitu() {
print('学校で勉強');
print('放課後は部活');
}
「heijitu」という名前の関数を作って、平日の内容をまとめて使い回せるようになります。
このように同じような処理をまとめて使い回せるのが関数です。
関数にもいくつか種類があるので、解説していきます。
void型:引数なし
上で紹介したように処理をまとめただけの関数です。
下記のような書き方をします。
void 関数名() {
まとめたい処理を書く
}
下記のコードをDartPadで実行してみてください。
void main() {
total();
}
void total() {
print(30 + 60);
}
「total」関数を作って、30 + 60を計算してConsoleに表示する処理を書いています。
その「total」関数を2行目で呼び出して使っています。
void型:引数あり
下記のような書き方をします。
void 関数名(型 引数1, 型 引数2) {
引数1と引数2を使った処理を書く
}
下記のコードをDartPadで実行してみてください。
void main() {
total(40, 50);
}
void total(int taro, int jiro) {
print('太郎と次郎の合計点');
print(taro + jiro);
}
「total」関数で太郎と次郎の点数を受け取れるように、「taro」「jiro」という名前とつけた引数を用意します。
2行目で呼び出した「total」関数に太郎と次郎の点数を渡すことで、2人の合計点を計算させます。
↓データの動き方
return型:引数なし
return型では処理した結果をデータに変換します。
下記のような書き方をします。
型 関数名() {
まとめたい処理を書く
return 処理した結果のデータ
}
下記のコードをDartPadで実行してみてください。
void main() {
int totalPoint = getTotal();
print(totalPoint);
}
int getTotal() {
int total = 30 + 60;
return total;
}
「getTotal」関数では30+60の計算結果90を、変数「total」に入れて、変数「total」をreturnしています。
この「getTotal」関数を呼び出すと、変数「total」に変換されます。つまり90に変換されます。
↓データの動き
return型:引数あり
受け取った引数を使って処理をして、その結果に変換する関数です。
下記のような書き方をします。
型 関数名(型 引数1, 型 引数2) {
引数1,引数2を使って処理する
return 処理した結果のデータ
}
下記のコードをDartPadで実行してみてください。
void main() {
int totalPoint = getTotal(50, 60);
print('太郎と次郎の合計点');
print(totalPoint);
}
int getTotal(int taro, int jiro) {
int total = taro + jiro;
return total;
}
「getTotal」関数で太郎と次郎の点数を受け取れるように、「taro」「jiro」という名前とつけた引数を用意します。
2行目で呼び出した「getTotal」関数に太郎と次郎の点数を渡すことで、2人の合計点110に変換されて、変数「totalPoint」に入ります。
↓データの動き方
非同期処理
ここはとても難しいです。初めての方にはなかなか理解しづらいと思います。
今は「そういうものがあるんだなぁ」くらいで結構です。
アプリを作る時に何度も出てくると思うので、その度に復習していただければ、徐々に理解が進むかと思います。
非同期処理とは
今まで紹介してきたコードは一つずつ順番に処理されます。これは同期処理と言います。
そうではなく、複数の処理を同時に行うのが非同期処理です。
↓こんなイメージです
下記のコードをDartPadで実行してみてください。
void main() {
print('処理1');
// ↓2秒待った後に print('処理2'); を行う
Future.delayed(Duration(seconds: 2)).then((result) {
print('処理2');
});
print('処理3');
}
Consoleの内容は
処理1
処理3
処理2
という順番になります。
処理の流れを図にするとこんなイメージです↓
非同期関数とは
非同期関数とは、非同期な処理を含む関数のことです。
↓例
Future<void> future() async {
// ↓2秒待った後に print('処理'); を行う
await Future.delayed(Duration(seconds: 2));
print('処理');
}
非同期関数を作るには「Future<型>」で関数の型を宣言し、「{}」の前に「async」を追加します。
非同期関数(void型)
非同期処理を含むvoid型の関数です。
下記のような書き方をします。↓
Future<void> 関数名() async {
await 非同期処理;
}
非同期関数(return型)
非同期処理を含むvoid型の関数で、処理が終わったら結果をデータに変換します。
下記のような書き方をします。↓
Future<型> 関数名() async {
await 非同期処理;
return 結果のデータ;
}
クラスとインスタンス
クラスとは
クラスとはどんなものかを表した設計図のようなものです。
例えば、ゲームの中にモンスターが出てくるとします。
モンスターの設計図としてモンスタークラスを考えます。
↓こんな感じです
クラスの書き方↓
class クラス名 {
final 型 変数名1;
final 型 変数名2;
クラス名({required 変数名1, required 変数名2});
型 関数名() {
何らかの処理・・・
}
}
変数名1、変数名2は、クラス(設計図)はどんな情報を持っているかを設定します。
モンスターの体力や攻撃力のような情報です。
関数はクラス(設計図)はどんな行動ができるかを設定します。
モンスターの攻撃するという行動のようなものです。
モンスタークラスをコードにするとこんな感じになります。
↓
class Monster {
final int hitPoint; // 体力
final int attackPoint; // 攻撃力
// インスタンス化した時に、体力と攻撃力を設定するためのコード
Monster({required this.hitPoint, required this.attackPoint});
// 攻撃する行動
void attack() {
print('相手に');
print(attackPoint);
print('のダメージを与える');
}
}
インスタンスとは
インスタンスとはクラス(設計図)から生み出された実物のようなものです。
クラスを実物として生み出すことをインスタンス化と言います。
先ほどのモンスタークラスをインスタンス化して実物にします。
↓こんな感じです
モンスタークラスをインスタンス化するコードを書くとこんな感じになります。
↓
// 体力50・攻撃力10のモンスターをインスタンス化して、Monster型の変数「pikachu」に入れる
Monster pikachu = Monster(hitPoint: 50, attackPoint: 10);
// インスタンス化したモンスター「pikachu」に「攻撃する」という行動をさせる
pikachu.atack();
インスタンス化したものを後から使うためには、作ったクラスの型の変数に入れる必要があります。
この場合は、Monsterクラスをインスタンス化したので、Monster型の変数「pikachu」に入れています。
クラスとインスタンスを使ったコードを動かす
Monsterクラスとそのインスタンスを使ったコードを動かしてみましょう。
下記のコードをDartPadに書いて実行してみてください。
void main() {
// 体力50・攻撃力10のモンスターをインスタンス化して、Monster型の変数「pikachu」に入れる
Monster pikachu = Monster(hitPoint: 50, attackPoint: 10);
// インスタンス化したモンスター「pikachu」に「攻撃する」という行動をさせる
pikachu.atack();
}
// モンスタークラス(設計図)を作る
class Monster {
final int hitPoint; // 体力
final int attackPoint; // 攻撃力
// インスタンス化した時に、体力と攻撃力を設定するためのコード
Monster({required this.hitPoint, required this.attackPoint});
// 攻撃する行動
void attack() {
print('相手に');
print(attackPoint);
print('のダメージを与える');
}
}
お疲れ様でした
ややこしい説明をたくさんしてしまい、すみません。
特に後半は難しい内容が多く、読むのを辞めたくなった方も多いのではないでしょうか。
ここまで辿り着いたあなたはすごいと思います!
何度かお伝えしていますが、暗記は不要です。
この内容を1発で全て理解するのは天才じゃないと難しいです。
もっと分かりやすく説明が思いついたら更新していきます。
実際にアプリを作りながら学べる教材も用意する予定ですので、よければ使ってみてください。
最後まで読んでくださり、ありがとうございました!