言語編 |
Dart言語は以下の型に対して特別なサポートをしている:
数値(numbers)
文字列(strings)
ブール値(booleans)
リスト(lists)(アレー(arrays)としても知られる)
マップ(maps)
ルーン文字(runes) (文字列内のUnicoode文字の表現用)
シンボル(symbols)
これらはDartのcoreライブラリに収容されており、詳細はDartのAPI参照を見て頂きたい。
これらの型たちのオブジェクトはリテラルを使って初期化できる。例えば、'this is a string'は文字列のリテラルであり、またtrueはブール値のリテラルである。
Dartでは各変数はあるオブジェクト(あるクラスのインスタンス)を参照しているので、変数を初期化するには通常コンストラクタが使える。組込み型のあるものはそれ自身のコンストラクタを有している。例えば、マップを生成するにはMap()コンストラクタが使える。
Dartには下図のように64ビットの2の補数方式の固定小数点であるint(但しJavaScriptでのビット演算は32ビット)と、64ビット倍精度浮動小数点のdoubleの2つが用意されている。これらはともにnumという抽象クラスを実装している。numはまたComparableインターフェイスを実装している。
|
整数の値はプラットホームに依存し、64ビットまたはそれ以下の値である。Dart VM上では、その値は-263 から 263 - 1の範囲となる。 JavaScriptに変換されたDartはJavaScriptの数値を使用していて、-253 から 263 – 1の値が許される。
注意:JavaScriptに変換されたDartコードの場合は、整数は倍精度浮動小数点値で表現されうる値に制限される。従って使える整数は -2^53 と 2^53 の範囲及びより大きな値の一部の整数(これには一部の2^63より大きな数が含まれる)である。従ってintクラスの演算子とメソッドの振る舞いはDart VMとJavaScriptにコンパイルされたDartコードとでは差が生じることがある。例えば、JavaScriptにコンパイルされたときはビット演算子は32ビットの整数に切り捨てられる。
IEEE 754標準で規定されている64ビットの不動小数点の数値である。なお0.0/0.0は浮動小数点の数字ではないのでNAN(Not a number)という扱いになる。それ以外の0での除算はプラスまたはマイナスの無限大(Infinity)になる。:
|
intとdoubleの双方はnumのサブタイプである。従って数値変数を宣言するときはint、double、あるいはそのどちらかでも良いときはnumという型指定を行う。
|
この例の4行目のintvalに対するint指定はエラーとなる。従ってdouble、numまたはvarで宣言しなければならない。
num型は+, -, /, 及び *といった基本的な演算子を含んでおり、またabs(), ceil(), 及び floor()などといったメソッドが存在する。(>>などのビット単位演算子はintクラスの中で定義されている。)numとその副型に自分が探しているものがないときはdart:mathライブラリにある可能性もある。
以下はnumクラスのなかのメソッドから有用と思われるものである:
|
整数は小数点のない数である。以下に整数リテラルを定義している幾つかの例を示す:
|
小数点が含まれる数はdoubleである。以下にdoubleのリテラルを定義している幾つかの例を示す:
|
Dart 2.1時点では、整数リテラルは必要に応じ自動的にdoubleに変換される:
|
バージョン版に関して: Dart 2.1版以前ではdoubleのコンテキスト内で整数リテラルを使うのはエラーだった。
以下は文字列と数値の変換例である:
|
int型では一般的なビット単位の演算子であるシフト(<<, >>)、and(&)、及びor(|)が規定されている。例えば:
|
リテラル数はコンパイル時常数である。多くの代数式もまた、その被演算物が数に計算されるコンパイル時常数である限りコンパイル時常数である。
|
Dartの文字列はUTF-16コード単位の並びである。文字列を生成するのにはシングル・クオートまたはダブル・クオートのいずれかが使える:
|
${式}を使ってある文字列内にある式の値を置くことができる。これは文字列内挿(string interpolation)とも呼ばれる。もしその式がある識別子であるときは{}をスキップできる。あるオブジェクトに対応した文字列を取得する為、DartはそのオブジェクトのtoString()メソッドを呼ぶ。
|
注意:==演算子はふたつのオブジェクトが等価であるかどうかをテストする。2つのオブジェクトの中身がコード単位で同じシーケンスであるときは等価である。
隣接文字列リテラルまたは+演算子を使って文字列を連結できる:
|
複行文字列を生成する別の手段:シングル・クオートまたはダブル・クオートのマークによるトリプル・クオートを使用する:
|
rをプレフィックスとして付すことで「生」文字列を生成できる:
|
文字列内のUnicode文字の表現法の詳細はRunesを見られたい。
内挿された式がリテラル文字列、nullまたは数値、文字列、またはブール値として計算されるコンパイル時常数である限り、リテラル文字列はコンパイル時常数である。
|
文字列の使用に関しては「Stringsと正規表現」を参照されたい。
ブール値を表現する為に、Dartはboolと称する型を有している。型boolには2つのオブジェクトのみがある:ブール値リテラルのtrueとfalseのであり、その双方はコンパイル時常数である。
Dartが型安全だということは、if (nonbooleanValue)またはassert (nonbooleanValue)のようなコードは書けないということである。その代わりとして以下のように明示的に値をチェックことになる:
|
おそらく殆どのプログラミング言語で最も共通的なコレクションはアレイ、または順序付けられたオブジェクトのグループであろう。DartではアレイはListオブジェクトであり、殆どの人たちは単にリストと呼んでいる。
Dartのリスト・リテラルはJavaScriptのアレイ・リテラルと似ている。以下はシンプルなDartのリストである。
|
注意:Dartのアナライザはこのリストは型List<int>だと推論する。このリストに非整数のオブジェクトを追加しようとすると、アナライザあるいはランタイムがエラーを生起する。より詳細は型推論に関する記事を読まれたい。
リストはゼロ・ベースのインデックス化を使っており、0は最初の要素のインデックスであり、list.length – 1は最後の要素のインデックスである。ちょうどJavaScriptと同じように、あるリストの長さを取得したりリスト要素を参照できる。
|
コンパイル時常数であるリストを生成するには、このリスト・リテラルの前にconstを付加する:
|
List型はリストの操作のための多くの便利なメソッドたちを有している。リストに関するより詳細な情報は「総称型」と「コレクション」の章を見て欲しい。
ここからはもう少し詳しくリストの使用法を解説する。
[]はリスト・リテラルを示すことになるので、
|
とあるListを宣言したとすると、それは
|
と宣言したと等価である。
リストの全要素の型が固定されているときは例えば次のように宣言できる:
|
また、
|
という宣言はlistという名前の宣言だけで、オブジェクトは生成されずnullであることに注意する。
|
最初のList myList;は変数を定義しただけで、オブジェクトは生成されない。従ってこれはnullと出力される。
nullのオブジェクトに対しては、myList.add("Hello");という操作はできない(NullPointerExceptionが生起される)。
myList = List();はコンストラクタを呼びオブジェクトが生成される。ここでは長さが0のオブジェクトである。これはvar myList[];あるいはList myList = [];という記述でも同じ効果を持つ。
これに対してはmyList.add("Hello");という操作が可能になる。
次の例では:
|
この例ではmyListというリストに2つの文字列と2つのdoubleの値が最初に含められている。
sという変数はなにもセットしないとnullのままなので、初期値として空の文字列''をセットする。空の文字列はnullではないので、他の文字列を連結させることができる。
リストの中身のインデックスは0から始まるので最後の値はmyList.lengthになる。
総てのオブジェクトのもとになっているObjectにはtoStringメソッドが定義されているので、これを使って総ての要素を文字列に変換して連結させている。但しDartはtoString()を付けなくても自分で判断してtoString()を呼び出す。各自確認されたい。
文字列が要素であるListのソーティングの例を次に示す。StringはComparable<String>を実装しているので、比較を使ったソートが簡単に実現できる:
|
ListはIterableを実装しているのでこのようにforEachメソッドが使える。4行目のprintの箇所は次のように記述できる:
|
比較関数としてcompareToが使われている。toLowerCaseで一旦小文字にして比較するのは、同じ英文字の大文字と小文字では大文字のコードが小さいので、'Zabc'が'aabc'よりも若くなってしまい、見づらくなる為である。このような使い方はComparableを実装しているBigInt, DateTime, Duration, num, Stringに適用できる。
ListはCollectionを実装しているので、このメソッドのreduceを使ってリストの中から最大または最小の要素をとりだすことも出来る。
|
バイト列はネットワークを介したデータ交換やファイル・データの取り扱いに良く使われるが、リストはバイト列を表現するのにも良く使われる。
|
これは'Dart言語'という文字列をUTF-8のバイト列に変換したものである。このようにbytesというバイト列はバイト(8ビット即ち0から255までの整数)の列になっている。
一般的に、マップはキー(keys)と値(values)を結び付けたオブジェクトである。キーと値の双方ともどの型のオブジェクトでもなり得る。各キーはただ1回生じるが、同じ値を複数回使うことは可能である。Dartのマップはマップ・リテラルとMap型でサポートされている。
以下では2つのシンプルなDartのマップがマップ・リテラルにより生成されている:
|
注意:アナライザはgiftsが型Map<String, String>でありnobleGasesがMap<int, String>だと推論する。いづれかのマップに対し間違った型の値を追加しようとすると、アナライザとランタイムはエラーを生起する。より詳細は型推論を読まれたい。
JavaScriptと同様に、既存のマップに新たなキー-値のペアを追加する:
|
マップから値を取り出すのもJavaScriptと同様である:
|
マップ内に無いキーを探そうとすると、戻り値にはnullが入る:
|
ー-値のペアの数を取得するには.lengthを使用する:
|
コンパイル時常数であるマップを生成するには、そのマップ・リテラルの前にconstを付加する:
|
{}はマップ・リテラルを示すことになるので、
|
とあるMapを宣言したとすると、それは
|
と宣言したと等価である。
また、
|
という宣言はmapという名前の宣言だけで、オブジェクトは生成されずnullであることに注意されたい。
簡単な番号案内のプログラムを示す:
|
Map型の電話帳であるdirectoryはStringの電話先とintの電話番号からなる。(この例では0から始まる番号は扱えない)
containsKey(s)というメソッドは指定したキーが存在するかどうかをboolで返す。
[s]という演算子は指定したキーの値を返す。
Map<K, V>の詳細はMapのAPI参照を見て頂きたいが、幾つかのメソッドとプロパティの使い方を示す:
|
DartではMapで記述したオブジェクトはJSONテキストと同じになる。dart:convertにはトップ・レベルの常数としてjsonが存在し、これはJsonCodecのデフォルト実装のインスタンスである。これを使ってMapの内容とJsonの文字列との変換を可能としている:
|
この結果はDartPadで確認されたい。このマップ(jsonObj)は"language"(文字列)、"targets"(リスト)、及び"website"(マップ)の3つの要素からなっている。これをjson.encodeメソッドを使ってJSONの文字列に変換したjsonStringも全く同じ文字列となる。ここでは逆にjson.decodeメソッドを使ってJSON文字列をMap型のオブジェクトに変換することも行っている。
このMapオブジェクトの各要素に対しては
|
というアクセスはできるが、通常のクラス・メンバのような
|
というようなアクセスは出来ない。
より詳細はライブラリ編の「dart:convert」に記されている。
Dartでは、ルーン文字はある文字列のUTF-32コード・ポイントである。
ユニコード(unicode)では世界中の綴字法システムで使われている文字、数字、及びシンボルの各々に対する数値を定めている。Dartの文字列はUTF-16コード単位の並びであるので、32ビットのUnicode値を文字列内で表現するには特別の文法が必要になる。
Unicodeコードポイントの通常の表現法は\uXXXXで、ここにXXXXは4桁の16進数である。例えば、ハート文字(♥)は\u2665である。16進数の4桁以上または4桁以下のものを指定するときは、その値を中括弧で囲む。例えば、笑い文字(😆)は\u{1f600}である。
ルーン文字を情報を抽出できる幾つかのプロパティがStringクラスにある。codeUnitAtとcodeUnitプロパティは16ビットのコード・ユニットを返す。ある文字列からルーン文字を取得するのにはrunesを使う。
次の例はルーン文字、16ビットのコード・ポイント、及び32ビットのコード・ポイント間の相互関係を示している。
|
このコードはDartPadで試すと良い。
注意:リストの操作でルーン文字を操作するのは注意を要する。このアプローチはとりわけ言語、文字セット、そして操作に依存して容易に失敗しうる。詳細はStack Overflow上のHow do I reverse a String in Dart?を見て欲しい。
SymbolオブジェクトはあるDartのプログラムの中で宣言された演算子または識別子を表現している。シンボルを使う必要は絶対出てこないかもしれないが、縮小化(minification)が識別子名を変えるが識別子のシンボルたちを変えないので、これらは名前によって識別子を参照するAPIでは貴重である。
ある識別子のシンボルを取得するには、シンボル・リテラル使用する。これは#の後に識別子を置いたものである:
|
Symbolリテラルはコンパイル時常数である。