Edited at

Dart2基本構文と機能のメモ


はじめに

自分が忘れないようにするためのメモの趣向がつよいです。

ゆっくりメンテしていきます。

編集リクエスト歓迎です。

本当はlanguage-tourに日本語版又はリポジトリがあればそれの和訳とかやりたかったんですが無さそうだったのでこんな感じでメモっていこうかなと。


参考資料

https://www.dartlang.org/guides/language/language-tour


サンプルコードリスト

https://github.com/k-okina/practice-dart


全てがObject


const 編

void main() {

const List<int> b = [1,2,3]; // OK(const値)
// b[0] = 4; // コンパイルエラー(指す先も変更不可)
List<int> c = b;
// c[0] = 4; // コンパイルエラー(指す先も変更不可)
c = [2,3,4];
print(c);
}


final編

void main() {

final List<int> b = [1,2,3]; // OK
b[0] = 4; // コンパイルエラーにならない
// b = [1, 2, 3]; // コンパイルエラーになる
}


constとfinalの違い

finalはキーワードを付与した変数は再代入禁止になるが、その変数が束縛している先は再代入を許可する。

jsのconstと挙動は同じ。

constは束縛している先も再代入を許可しない。

jsのObject.freezeを付けてくれる感じ。


コンパイル時定数(compile time constant)

まぁこんな感じ。

リテラルを固めてくれる

void main() {

List<int> b = const [1,2,3];
// b[0] = 4; // コンパイルエラー(指す先も変更不可)
b = [1,2,3]; // OK
}


listの挙動その1

まぁここまではjsと同じ

void main() {

List<int> a = [1,2,3];
List<int> b = a;
List<int> c = new List<int>.from(b);
b[1] = 3939;
c[1] = 4649;
print(a); // [1, 3939, 3]
print(b); // [1, 3939, 3]
print(c); // [1, 4649, 3]
}


map

正常系

void main() {

// String -> int
const Map<String, dynamic>map = {
'value': 'fuga',
'child': {
'value': 3939,
'child': {
'value': 4649
}
}
};

print(map); // {value: fuga, child: {value: 3939, child: {value: 4649}}}
print(map['fuga']); // null
print(map['value']); // 'fuga'
print(map['child']); // {value: 3939, child: {value: 4649}}
// mapのvalueをdynamicにしないと、childのchildにたどり着けない。(型推論の影響
print(map['child']['child']); // {value: 4649}
print(map['child']['child']['value']); // 4649
}

異常系

型推論弱い。

リテラルで与えてるんだからもうちょっと頑張って欲しいけど型推論はTypescriptとかの方が全然強そう。

void main() {

// String -> int
const map = const {
'value': 'fuga',
'child': {
'value': 3939,
'child': {
'value': 4649
}
}
};

// The method '[]' isn't defined for the class 'dart.core::Object'.
print(map['child']['child']);
}


Symbol

こんな感じ.

# prefiではじめるそう。

JSのSymbolとは別物の模様。

もちろんSymbolクラスから生成もできる

void main() {

Symbol hoge = #helloworld;
print(hoge == #helloworld); // true
print(hoge == #helloworld2); // false

Symbol fuga = new Symbol('helloworld');
print(hoge == fuga); // true
print(fuga == new Symbol('helloworld')); // true
}


関数

関数。

アロー演算子みたいなのも使えるみたい。

void main() {

int a(int a) => a * a;
Function b(int b) => (int c) => b * c;
Function c = (int d) => d * d;

print(a(10)); // 100
print(b(10)(20)); // 200
print(c(200)); // 40000
}

この辺もjsライク

int stock = 0;

int add(int value) {
stock += value;
return stock;
}

void main() {
const a = 1000;
int b(int c) {
return a + c;
}
print(b(10)); // 1010
print(add(10)); // 10
print(add(10)); // 20
}


cli


良い感じに分解してくれる

void main(List<String> args) {

// $ dart print_args 1 2 3 4 hello world
// ってやると
// [1, 2, 3, 4, hello, world]
// って出力される
print(args);
}


攻撃の耐性もある

どこまで攻撃耐性あるのかわからないけどこの程度のは自動で防いでくれた

void main(List<String> args) {

// $ dart print_args2.dart $hello
// []
// $ dart print_args2.dart ${hello}
// []
// $ dart print_args2.dart hoge${hello}
// [hoge]

const hello = 'hogehoge';
print(args);
}


型キャスト

正常例

void main() {

// String -> int
int one = int.parse('1');
print(one); // 1

// String -> double
double onePointOne = double.parse('1.1');
print(onePointOne); // 1.1

// String -> double -> int
double number = double.parse('123.6');
print(number.round()); // 123
print(number.round() is int); // true
print(1.0 is double); // true
print(1.0 == 1.000000); // true
print(1.0 == 1); // true
print('1' == 1); // false

// int -> String
String oneAsString = 1.toString();
print(oneAsString); // 1

String piAsString = 3.14159.toStringAsFixed(2);
// 小数点2桁まで保持にしてるの
print(piAsString); // 3.14
}

異常例

void main() {

// FormatException: Invalid radix-10 number
int.parse('123.6');
// FormatException: Invalid radix-10 number
int.parse('123hello');
}


assert

--enable-assertsオプションを付けた際にassertにtrueが渡らなかった場合その時点でエラーを吐いてプログラムを停止してくれる。

--enable-assertsがついてなかったら(本番時とか)assertは無視される。

ちなみにflutterの場合開発モードだと常に--enable-assertsがついてる模様。

$ dart --enable-asserts assert.dart


assert.dart

void main() {

// String -> int
int one = int.parse('1');

// Failed assertion: line 4 pos 10: 'one == 2': is not true.
assert(one == 2);

// Failed assertion: line 7 pos 10: 'false': is not true.
assert(false);
}