Dart基礎文法など【備忘録】

## はじめに
今回、Flutterを使用するにあたりDart言語が必要だと聞いて初めて触るので勉強の備忘録として残ていきます。

**環境構築不要で練習できる公式サイトリンク**

https://dartpad.dev/

# アジェンダ

1. [はじめに](#はじめに)
2. [変数について](#変数について)
   - 型の種類
   - ミュータブルな変数
   - イミュータブルな変数
3. [コレクション](#コレクション)
   - List
   - Map
   - Set
4. [使えそうなメソッド](#使えそうなメソッド)
   - forEach
5. [演算子](#演算子)
6. [変数の扱い方](#変数の扱い方)
   - 文字列結合
7. [条件式](#条件式)
   - if文
   - switch文
8. [ループ文](#ループ文)
   - for文
   - while文
   - do-while文
9. [関数](#関数)
   - 基本的な関数
   - 名前付き引数
10. [クラスとプライベート変数](#クラスとプライベート変数)
    - プライベート変数
11. [最後に](#最後に)
12. [参考資料](#参考資料)

https://dartpad.dev/

## 変数について
### 型の種類(抜粋)
| 型          | 説明                                                         | 使用用途例                                                 |
|-------------|--------------------------------------------------------------|------------------------------------------------------------|
| `int`       | 整数型。整数値を格納する                                       | 年齢、価格、数量などの整数値                               |
| `double`    | 浮動小数点型。小数点を含む数値を格納する                     | 重さ、温度、金額などの小数を含む数値                       |
| `String`    | 文字列型。文字列（テキスト）を格納する                       | 名前、住所、メッセージなどの文字列データ                   |
| `bool`      | 真偽値型。`true` または `false` の値を格納する               | 条件式、フラグ、チェックボックスの状態などの論理値         |
| `List<T>`   | リスト型。順序付けられた要素を格納する集合。`T`は要素の型     | 数字や文字列のコレクション（例：`List<int>`, `List<String>`）← Cとかでいう配列|
| `Set<T>`    | セット型。重複しない要素を格納する集合。`T`は要素の型         | 一意な値の集合（例：`Set<int>`, `Set<String>`）             |
| `Map<K, V>` | マップ型。キーと値のペアを格納する。`K`はキーの型、`V`は値の型 | 辞書や連想配列のようなデータ（例：`Map<String, int>`） ←　Pythonでいう辞書型     |





### **ミュータブルな変数**
**基礎文法**

**```var　型名　変数名 = 値;```**

varの場合は型名が省略できるらしく

**``var 変数名 = 値;``**

としてDart側が自動で型を認識してくれるらしい

  
   変数の型を後で変えられない形で変数を定義する
	
 ```Dart
	void main(){
		var  a = 2; // int型と推論
		
		var int b = 3; // int型として明示的に定義
  
		b = "Hello World"; // 型が異なるためエラー
		
		print("$aです");
	}
```


- **```型名　変数名 =　値```**　と記述しても同じ認識を受ける
 (暗黙的にvar型として認識される)
```Dart
	void main(){
	    int a = 2; // 暗黙的にvar型になる(型の変更不可)
		
		print("$aです");
	}
```

**型名変更可能な書き方**
 「```dynamic型```」にする

**文法**

**```dynamic 変数名 = 値;```**

例
```Dart
void main(){
	dynamic a = 2; // intとして自動認識

	print("$a"); // 「2」と表示

	a = "Hello World";

	print("$a"); // 「Hellow World」と表示
	
}
```


---


### イミュータブルな変数
**基礎文法**

 **```const 型名　変数名 = 値;```**

 **```final 型名　変数名  = 値;```**

**```const```**
- コンパイル時に値が確定し、それ以降変更できない
  - 使用例：完全な不変な値(変数)となるので定数の定義とかにするイメージ

**```final```**
- プログラム実行時で値が確定し、それ以降変更できない



わかりやすめの例：
```Dart
void main(){
	final int list1 = [1,2,3];
	
	const int list2 = [1,2,3];

	list1[0] = 4;  // リストの中身自体は変更可能

	list2[0] = 4;  // エラー
}
```
---

## コレクション
### list

**基本文法**
**``List<型名> 変数名 = [値1,値2,...,値n];``**
**``var a = [値1,値2,...,値n];``**

例 **①普通に配列文回してfor文で表示**
```dart
void main() {
  List<int> a = [2, 4, 6, 8, 10];
  
  for (int i = 0; i < a.length; i++) {
    print(a[i]);  // 2,4,6,8,10
  }
}
```
例 **②var型で定義してみる(これなら型不問)**
( **``List<dynamic>``** でも実質同じことができる。)
```dart
void main() {
  var a = ["a","b","c",4,true]; 
  
  for (int i = 0; i < a.length; i++) {
    print(a[i]);  // a,b,c,4,true 
  }
}
```
### Map
Dartでは辞書型のことを「 **map** 」というらしいです。
基本的にはPythonなどと書き方や認識は変わりません
**基本文法**
 **``Map<Keyの型名><値の型名> = {キー1:値1,キー2,値2,...キーn,値n};``**

 
 例 **Map型の例(var型で自動認識)**
 ```dart
 void main() 
{
  // マップの作成
  var fruitsMap = {
    'りんご': 1,
    'みかん': 2,
    'もも': 3
  };

  for (var fruits in fruitsMap.entries) {
    print('${fruits.key}: ${fruits.value}'); // 辞書の中身を表示
  }
}
 ```
 --- 
 ### Set
 Setは集合であり、以下の特性を持つらしい
 - **重複が許されない** : 同じ値を複数回追加しても、1つしか保持されない
 - **順序が保証されない** : 順序に依存しないため、アクセス時の順番が異なる可能性がある
 - **高速な検索・挿入** : 内部的にハッシュベースのデータ構造を使用するため、要素の検索や挿入が高速である(らしい)

 **基本文法**
 
 **``Set<int> = {値1,値2,値3,...,値n};(順番関係ない)``**
 
例 **Setの操作**
```dart
void main() {
  // Set<int>の初期化
  Set<int> a = {1, 2, 3, 3, 5, 6};

  // Setの内容を表示
  print("Set a の内容: $a"); // 1,2,3,5,6

  // 要素を追加
  a.add(4);
  print("4を追加後 4: $a"); // 1,2,3,5,6,4

  // 要素を削除
  a.remove(5); 
  print("5を削除後: $a"); // 1,2,3,6,4

  // 特定の要素が含まれているか確認
  bool inThree = a.contains(3);
  print("3が入っているか 3? $inThree"); // True

  // Setの長さ
  print("Set a の長さ: ${a.length}"); // 5

  // Setをループで表示
  for (int value in a) {
    print(value);
  }
}

```


### 使えそうなメソッド
**``forEach``**　→ いちいちfor文で配列の回数ループする条件を書かなくてもこのメソッドを呼び出すだけで配列分のループ回せる
**基本文法**
 **``配列名.forEach(配列の中身を入れる変数名)({処理内容});``**


例 **①listやsetでの書き方(setはほぼ書き方同じなため割愛)**
```dart
void main() 
{
  // リスト定義
  List<int> a = [2, 4, 6, 8, 10];

  // forEachでリスト中身表示ループ
  a.forEach((i){
    print(i); 
  });
}

```
例　**②Mapでの使用例**
```dart
void main() 
{
  // マップの作成
  var fruitsMap = {
    'りんご': 1,
    'みかん': 2,
    'もも': 3
  };

  // forEach でマップの中身を表示
  fruitsMap.forEach((key, value) {
    print('$key: $value'); 
  });
}

```

---


### 演算子
**基本的な演算子一覧**

| 演算子               | 説明                                                         | 使用用途例                                                 |
|----------------------|--------------------------------------------------------------|------------------------------------------------------------|
| `+`                  | 加算（加法）                                                 | `5 + 3` → 8                                                |
| `-`                  | 減算（減法）                                                 | `10 - 2` → 8                                               |
| `*`                  | 乗算（乗法）                                                 | `4 * 3` → 12                                               |
| `/`                  | 除算（除法）                                                 | `10 / 2` → 5.0                                             |
| `~/`                 | 整数除算（商の整数部分）                                     | `10 ~/ 3` → 3                                              |
| `%`                  | 剰余（余り）                                                 | `10 % 3` → 1                                              |


### 変数の扱い方
**文字列結合**
変数に値を代入する際、文字列と変数名を「**```$変数名```**」という形でやれば文字列の中に変数の中に入っている値を文字列として入れる
**文法**
① **```String(かdynamic) 変数名 = "代入したい文字列 $変数名";```**
② **```String(かdynamic) 変数名 = "代入したい文字列 ${変数名};　代入したい文字列";```**

②の場合続けて文字列を代入できる



例
```Dart
void main(){
  int result1 = 1 + 2; // 3
  int result2 = 6 - 2; // 4
  
  String title1 = "result1 = $result1"; 
  
  String title2 = "result2 = ${result2}x";
  
  print(title1); // 「result1 = 3」 と表示
  print(title2); // 「result2 = 4x」と表示 
}
```
---
## 条件式

言わずもがなの条件文ことif文です。
書き方も他言語(ブロック構造)経験者ならばすんなり理解できると思います。
**基本文法**

**`` if(条件式){処理} ``**

ほかの条件を付けたい場合は **``else{処理}``**　か　**``else if(){処理}条件式
{}``**　で実現できます。

例
```dart
void main(){

    var a = 10;
    var b = 20;

    if(a > b){
        print("aはbより大きいです");
    }else if(b > a){
        print("bはaより大きいです");
    }else{
        print("aとbは等しいです");
    }

}
```
### Switch文
これも同じみな文ですね

**基本文法**

 **```switch(値){```**
 **``case 値：処理``**
 **``break;``**
 **``default:処理 }``**

 他言語でもよくある書き方ですね。
 
例
```dart
void main() {
  var a = 10; 

  switch (a) {
    case 10:
      print("10です");
      break;
    case 20:
      print("20です");
      break;
    default:
      print("10でも20でもありません");
      break;
  }
}


```

## ループ文

これもC言語や,Javaなどに似ている構文をもっています。

**基本文法**
**``for(型　変数名; ループの条件; 更新){}``**
    **``while(ループ条件)``**　←前判定繰り返し
**``do～while(ループ条件)``**  ←あと判定繰り返し

例 ①for文例(10までカウントアップ)
```dart
void main(){
    for(int i = 1; i <= 10; i++){
        print("$i");
    }
}
```
例 ②while文例（10までカウントアップ）
```dart
void main(){
 
  int i = 1;

  while (i <= 10) {
    print("$i");
    i++;
  }
  
}

```
例 ③do,while文例(10までカウントアップ)
```dart
void main() {
  int i = 1;

  do {
    print("$i");
    i++;
  } while (i <= 10);
  
}

```
---


## 関数
**関数の基本文法について**

- **```返り値の型 関数名(引数1の型 引数名 , 引数2の型 引数名 , ・・・)```**

**引数,返り値を設定しないとき**
 - 返り値の部分に **```void```** を設定
 - 引数は **```()```** で何も入れない（ **```void```** 明示的に指定できない)　← メイン関数がいい例

 **関数呼び出しについて**

ここに関してはJavaやC言語とほぼ同じく

**``関数名(引数1,引数2)``**


**実際のコード例**
```Dart
// 引数1と引数2を足し算する関数
int add(int num1, int num2) {
  
  int sum = num1 + num2;

  return sum;
}

// 今回メイン関数は引数もなにもないので両方voidを指定
void main() {
  int a = add(3, 7);

  print("計算結果は$aです"); // 「計算結果は10です」と表示
}
```
**名前付き引数**

引数に名前を定義することにより引数を受け渡す際の順番にとらわれないようにするためのもの

さっきまでの引数の例は「**位置引数**」といい、呼び出し時に受け渡す引数の位置で仮引数の値も決定する。

**名前付き引数**は順番にとらわれないため実引数で変数名を明示的にする必要がある

仮引数定義の指定の際に``()``の中に``{}``を指定する。

**```required```**（必須の引数として）を付けないで定義できる。

その場合,何も引き渡されなかったときは「**``null``**」が入ってしまうので,
それを許容する場合は「**``?``**」演算子を利用する。

それか「**引数を定義する際に初期化をする**」必要がある。
その場合は「**``?``**」は必要ない。
(初期化しないと 四則演算などが **``null``** どうしでは行えないし,表示もできないので)←こっちのほうが安全ではありそう...?


**基礎文法**
① **```戻り値の型　関数名({required 引数1の型名 引数1の変数名 , required 引数の2型名 引数2の変数名・・・})```**
② **```戻り値の型　関数名({引数1の型名? 引数1の変数名 ,引数の2型名? 引数2の変数名・・・})```**


例 **①数値の名前付き引数の場合**
```dart
// 引数1と引数2を足し算する関数
int add({int num1 = 0, int num2 = 0}) {
  
  int sum = num1 + num2;

  return sum;
}

// 今回メイン関数は引数もなにもないので両方voidを指定
void main() {
  int a = add(num1:3,num2:7);

  print("計算結果は$aです"); // 「計算結果は10です」と表示
}
```
例 **②文字列の名前付き引数の場合**
```dart
// 引数で指定された名前を使って挨拶を作る関数
String greet({String? name1, String? name2}){
  String message = "こんにちは" + name1.toString() + "さん!! ";
  message += name2.toString() + "さんもこんにちは!!";
  return message;
}

// メイン関数
void main() {
  // 第一引数のみ渡して関数を呼び出し
  String greeting = greet(name1:"太郎"); 
  
  print(greeting); // 結果: こんにちは太郎さん!! nullさんもこんにちは!!
}
```

例　③ **requiredを付けて引数を指定しなかった場合(エラー)**
```dart
// 引数で指定された名前を使って挨拶を作る関数
String greet({required String name1,required String name2}){
  String message = "こんにちは" + name1 + "さん!! ";
  message += name2 + "さんもこんにちは!!";
  return message;
}

// メイン関数
void main() {

  // 第一引数のみを渡して関数を呼び出し
  String greeting = greet(name1:"太郎");  //　「name2」呼び出してないのでエラー
  
  print(greeting); 
}
```

## クラスとプライベート変数
### プライベート変数について
「**_**」アンダースコアを変数名の前につけるプライベート変数になる

**文法**
型名 _変数名 = 値

例
```Dart
class Forexample {

  int _ad = 1; // プライベートメンバ

  void reference()  {
    _ad = 2; // クラス内ではアクセス可能
    print("「_ad」変数を変更 $_ad");
  }

  // ゲッターメソッド
  int getAd() {
    return _ad;
  }

  // セッターメソッド (value を使って _ad を変更)
  set setAd(int value) {
    _ad = value;
    print("「_ad」変数を変更（セッター経由） $_ad");
  }
}

class Ex2 extends Forexample {

  void changeAd(int value) {
    // セッターを使って _ad を更新
    setAd = value; // セッターを使って _ad を変更
    print("「_ad」は親クラスのセッター参照で変更されました。");
  }
}

void main() {
  Forexample forexample = Forexample();
  print(forexample.getAd()); // 出力: 1

  forexample.reference(); // _ad を更新
  print(forexample.getAd()); // 出力: 2

  Ex2 ex2 = Ex2();
  ex2.changeAd(10); // セッターを使って _ad を 10 に変更
  print(ex2.getAd()); // 出力: 10
}



```
---


## 最後に
ここまでのご閲覧ありがとうございました。
備忘録なので随時この記事は更新していきますのでご期待ください。
また、Flutterについても備忘録を記事にしております以下のリンクからぜひご覧ください

https://qiita.com/nanashi39/items/e09b08da960b93afcd28


## 参考にさせていた記事,資料

https://qiita.com/sebayashi-tomoya/items/25e9124061ca606da6f5

https://qiita.com/uehaj/items/7c07f019e05a743d1022

https://zenn.dev/flutteruniv_dev/articles/554e72698180df

https://www.udemy.com/course/nzigen-flutter_beginner/?couponCode=BFCPSALE24JP