はじめに
自分が忘れないようにするためのメモの趣向がつよいです。
ゆっくりメンテしていきます。
編集リクエスト歓迎です。
本当はlanguage-tourに日本語版又はリポジトリがあればそれの和訳とかやりたかったんですが無さそうだったのでこんな感じでメモっていこうかなと。
参考資料
サンプルコードリスト
全てが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
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);
}