とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

プログラミング言語Dart入門

編集中。
2011/10/16 ファクトリーコンストラクタ (Factory constructors) を追記

コメント

単一行コメント (single-line comment)
// コメント
複数行コメント (multi-line comment)
/* コメント
   コメント
   コメント */
ドキュメント用コメント (documentation comments)
/** ドキュメント用コメント
    コメント
    コメント
 */

main

スクリプトはトップレベル関数のmainから。

int main() {
  // プログラム
  //     :
}

出力

print()を使う

int main() {
  print('Hello, world!');
}
/*
Hello, world!
*/

リテラル (literal)

nullリテラル (nullLiteral)
null
真偽値リテラル (booleanLiteral)
true
false
数値リテラル (numericLiteral)
0
123
.123
123.456
123.456e7
123.456e-7
0xDEADBEEF
0Xc0ffee
文字列リテラル (stringLiteral)
"Hello, world!"
'Hello, world!\n' // エスケープシーケンス
"It's mine."
'He said "The Dart is cool."'
"""複数行
リテラル"""
'''multi
line
string'''
@'生文字列\n\r' // \n\r はエスケープシーケンスではない。
@"""複数行
\t生文字列"""
マップリテラル (mapLiteral)
{'one': 1}
<String, int>{'two': 2}
const{'three': '三'}
const<String, int>{'one': 1, 'two': 2, 'three':3}
リストリテラル (listLiteral)
[]
['hoge']
['foo', 'bar']
<int>[0, 1]
const[0, 1]
const<int>[0, 1]

変数と出力

int main() {
  int a, b = 10;
  var c = 20;
  final int d = 30;
  final e = 40;
  print(a);
  print('b == $b, c == $c, d == $d, e == ${e}');
}
/*
null
b == 10, c == 20, d == 30, e == 40
*/

関数

twice(var n) => n * 2;

twice2(var n) {
  return n * 2;
}

int cube(int n) => n * n * n;

int cube2(int n) {
  return n * n * n;
}

accumurate(var list) {
  int acc = 0;
  for(int i = 0; i < list.length; ++i)
    acc += list[i];
  return acc;
}

int main() {
  print(twice(2));
  print(twice2(3));
  print(cube(4));
  print(cube2(5));
  print(accumurate([]));
  print(accumurate([2, 3]));
}
/*
4
6
64
125
0
5
*/

ブロック (block)
{
 ;
 ;
 // :
}
for文 (forStatement)
  • For Loop
int main() {
  for(int i = 0; i < 10; ++i)
    print(i);
}
/*
0
1
2
3
4
5
6
7
8
9
*/
  • Foreach
int main() {
  for(var s in ['hello', 'world'])
    print(s);
}
/*
hello
world
*/
while文 (whileStatement)
int main() {
  var n = 3;
  while(n > 0) {
    print(n);
    --n;
  }
  print('---');
  while(n > 0) {
    print(n);
    --n;
  }
}
/*
3
2
1
---
*/
do文 (doStatement)
int main() {
  var n = 3;
  do {
    print(n);
    --n;
  } while(n > 0);
  print('---');
  do {
    print(n);
    --n;
  } while(n > 0);
}
/*
3
2
1
---
0
*/
switch文 (switchStatement)
int main() {
  final name = 'dart';
  switch(name) {
    case 'dart':
      print('Dart!');
      break;
    case 'ECMAScript':
      print('ECMAScript...');
      break;
    default:
      print('other');
  }
}
/*
Dart!
*/
if文 (ifStatement)
int main() {
  if(true)
    print(true);

  if(false)
    ;

  if(false)
    ;
  else
    print(false);
}
/*
true
false
*/
try文 (tryStatement)
int main() {
  try{
    switch(name) {
    case 'dart':
      print('Dart!');
      // ここで例外発生
    case 'ECMAScript':
      print('ECMAScript...');
      break;
    default:
      print('other');
    }
  }
  catch(var e)
  {
    print(e);
  }
  finally
  {
    print('finally');
  }
}
/*
Dart!
Switch case fall-through
finally
*/

ラベル・break文・continue文 (label, breakStatement, continueStatement)

int main() {
  A:
  for(int i = 0; i < 3; ++i) {
    B:
    for(int j = 0; j < 10; ++j) {
      if(j > 3)
        continue A;
      print('i == $i, j == $j');
      if(i > 1)
        break B;
    }
  }
}
/*
i == 0, j == 0
i == 0, j == 1
i == 0, j == 2
i == 0, j == 3
i == 1, j == 0
i == 1, j == 1
i == 1, j == 2
i == 1, j == 3
i == 2, j == 0
*/
return文 (returnStatement)
f() {
  return; // return null;
}
g() => 42; // return 42;
h() {
  return 64;
}
int main() {
  print(f());
  print(g());
  print(h());
}
/*
null
42
64
*/
throw文 (throwStatement)
int main() {
  try {
    throw "throw Exception!";
  }
  catch(String s) {
    print(s);
  }
}
/*
throw Exception!
*/
assert文 (assertStatement)
int main() {
  assert(true);
  try {
    assert(false);
  }
  catch(var e) {
    print('catch');
  }
}
/*
catch
*/

関数リテラル

final greet_world = (String greeting) => 
  print(greeting + ', world!');

final make_add_n = (int n) => (int m) => m + n;

int main() {
  ((int n) => print('$nが渡された'))(7);


  greet_world('Hello');

  var add_1 = make_add_n(1);
  print(add_1(2));

  var add_10 = make_add_n(10);
  print(add_10(5));
}
/*
7が渡された
Hello, world!
3
15
*/

クラス (class)

class test
{
  // declaration
  int member1;
  String member2;

  // factoryConstructor
  test(this.member1)
    : member2 = 'default words'
  {}
  
  method() {
    print(member1);
  }

  // static method
  static static_method() => print('called test.static_method()');

  // Getter
  String get str() => member2;

  // Setter
  String set str(String s) {
    member2 = s;
    return member2;
  }

  // operatorSignature
  bool operator== (test rhs){
    print('called test.operator==');
    return member1 == rhs.member1 && member2 == rhs.member2;
  }

  // namedConstructorSignature
  test.fact(this.member1, this.member2)
  {}
}

int main() {
  final instance = new test(10);
  print('instance.member1 == ${instance.member1}');
  instance.method();
  test.static_method();
  print(instance.str);
  instance.str = "new words";
  print(instance.str);
  final another = new test.fact(10, 'new words');
  print(instance == another);
}
/*
instance.member1 == 10
10
called test.static_method()
default words
new words
called test.operator==
true
*/

派生・継承・オーバーライド (extends)

class super_class
{
  int n;
  super_class(this.n)
  {}
  method() => print(n);
}

// 派生
class derived_class extends super_class
{
  String str;
  derived_class(int n, this.str)
    : super(n)
  {}
  // オーバーライド
  method() => print('${super.n}, $str');
}

int main() {
  final super_class s = new super_class(128);
  s.method();
  final super_class d = new derived_class(256, 'derived');
  d.method();
}
/*
128
256, derived
*/

インターフェイスと実装 (interface, implements)

interface drawable
{
  void draw();
}

class circle implements drawable
{
  void draw() {
    print('○');
  }
}

class square implements drawable
{
  void draw() {
    print('□');
  }
}

class triangle implements drawable
{
  void draw() {
    print('△');
  }
}

int main() {
  for(final e in <drawable>[new circle(), new square(), new triangle()])
    e.draw();
}
/*
○
□
△
*/

型パラメータ (typeParameter)

interface drawable
{
  void draw();
}

class holder<T> implements drawable
{
  T value;
  holder(this.value)
  {}
  void draw() {
    print(value);
  }
}

int main() {
  for(final e in <drawable>[new holder<int>(42), new holder<String>('Fizz'),
                            new holder<double>(3.14)])
    e.draw();
}
/*
42
Fizz
3.14
*/

ファイル先頭に書ける雑多なもの

#!/* /path/to/dart */       // スクリプトタグ。処理系はこの行を無視する
#library('library_name');   // このライブラリ名
#import('import/file');     // インポート
#source('include/file');    // インクルード
#resource('resource/file'); // リソースファイル(オーディオ,ビデオ,グラフィックファイルなど)

int main() {
  // :
}

ファクトリーコンストラクタ (Factory constructors)

普通コンストラクタはコンストラクトされた自分自身を返すが,ファクトリーコンストラクタを使うと自分自身以外を返すことができる。これによりすでに存在しているインスタンスを返したり(キャッシュ),別のクラスのインスタンスを返したりできる。

class Symbol {
  final String name;
  static Map<String, Symbol> _cache;

  // ファクトリーコンストラクタ
  factory Symbol(String name) {
    if (_cache == null) {
      _cache = {};
    }
    if (!_cache.containsKey(name)) {
      _cache[name] = new Symbol._constructor(name);
    }
    return _cache[name];
  }

  Symbol._constructor(this.name);
}

main() {
  { // 普通は異なるインスタンスを返す
    var a = new Object();
    var b = new Object();
    print(a === b);
  }
  { // ファクトリーコンストラクタでキャッシュを実装したので name が同じであれば同じインスタンスを返す
    var a = new Symbol('something');
    var b = new Symbol('something');
    print(a === b);
  }
}
/*
false
true
*/