組み込み型

import なしで使える型と、その型に付く関数。値のうしろに . を付けて呼ぶ。代入すると中身はコピーされる。

string.len string.sub string.find string.contains string.starts_with string.ends_with string.split string.trim string.upper string.lower string.replace string.bytes string.from_hex string.chars string.compare bytes.len bytes.push bytes.to_string bytes.list bytes.sub bytes.to_hex bytes.compare int.to_bytes int.wrapping_add int.wrapping_sub int.wrapping_mul int.compare float.infinity float.compare bool.compare list.push list.pop list.len list.insert list.remove list.contains list.join list.sort map.get map.has map.remove map.len map.keys map.values Result.ok Result.value Result.error Error.init Error.message Error.code Comparable.compare

string

Unicode の文字列。

内部は UTF-8 だが、添字も長さも文字(コードポイント)単位で数える。バイト単位で触りたいときは bytes() で変換する。

string.len() → int

文字数を返す。バイト数ではない。

print("さめ🦈".len());     // 3
string.sub(start: int, end: int) → string

start から end の手前までを取り出す。位置は文字単位。

startint最初の文字の位置(0 から)
endintここは含まない
print("さめ🦈".sub(0, 2));   // さめ
string.find(s: string) → int?

見つかった位置を返す。無ければ none。

print("さめざめ".find("ざ") ?? -1);   // 2
print("さめ".find("ふぐ") ?? -1);     // -1
string.contains(s: string) → bool

含んでいるか。

print("さめざめ".contains("めざ"));   // true
string.starts_with(s: string) → bool

その文字列で始まるか。

print("さめ.txt".starts_with("さめ"));   // true
string.ends_with(s: string) → bool

その文字列で終わるか。

print("さめ.txt".ends_with(".txt"));   // true
string.split(sep: string) → list<string>

区切り文字で分ける。

var xs = "さめ,ふぐ,あじ".split(",");
print(xs.len());     // 3
print(xs[1]);        // ふぐ
string.trim() → string

前後の空白(改行を含む)を落とす。

print("  さめ  ".trim() + "!");   // さめ!
string.upper() → string

大文字にする。

print("shark".upper());   // SHARK
string.lower() → string

小文字にする。

print("Shark".lower());   // shark
string.replace(from: string, to: string) → string

見つかった部分を全部置き換える。

print("さめさめ".replace("さめ", "ふぐ"));   // ふぐふぐ
string.bytes() → bytes

UTF-8 のバイト列にする。

print("さめ".bytes().len());   // 6
string.from_hex() → bytes?

16 進の文字列として読み、バイト列にする。

大文字と小文字のどちらでも読める。 16 進でない字が混じっていたり、長さが奇数なら none。

print("01ff".from_hex()!.len());   // 2
print("xyz".from_hex() == none);   // true
string.chars() → list<string>

1文字ずつの配列にする。

var cs = "さめ🦈".chars();
print(cs.len());   // 3
print(cs[2]);      // 🦈
string.compare(other: string) → int

並べ替えのための比較。コードポイント順で、小さいと負、等しいと 0。

print("あ".compare("い"));   // -1

bytes

バイトの並び。添字はバイト単位。

b"..." と書くとリテラルになる。文字として扱いたいときは to_string()。

bytes.len() → int

バイト数を返す。

print(b"\x01\x02".len());   // 2
bytes.push(v: int) → void

末尾に1バイト足す。

var b = b"\x01";
b.push(0x02);
print(b.len());   // 2
bytes.to_string() → string?

UTF-8 として文字列にする。壊れていれば none。

print("さめ".bytes().to_string() ?? "");   // さめ
bytes.list() → list<int>

1バイトずつの数の配列にする。

print(b"\x01\x02".list()[1]);   // 2
bytes.sub(start: int, end: int) → bytes

start から end の手前までを取り出す。位置はバイト単位。

print("さめ".bytes().sub(0, 3).to_string() ?? "");   // さ
bytes.to_hex() → string

16 進の文字列にする。小文字で、1バイトが2文字になる。

バイト列はそのままでは目に見えないので、見せたり書き残したりするときに使う。from_hex() で元に戻せる。

print(b"\x01\xff".to_hex());              // 01ff
print("さめ".bytes().to_hex().from_hex()! == "さめ".bytes());   // true
bytes.compare(other: bytes) → int

並べ替えのための比較。

print(b"\x01".compare(b"\x02"));   // -1

int

64ビットの整数。どの環境でも 64 ビット。

計算があふれると実行時エラーになる。あふれてよい計算には wrapping_ を使う。ビット演算(& | ^ ~ << >>)と冪乗(**)も書ける。動きは C と同じ。

int.to_bytes() → bytes

8バイトのバイト列にする。小さい桁が先(リトルエンディアン)。

var b = 258.to_bytes();     // 258 は 0x0102
print(b.len());             // 8
print(b.list()[0]);         // 2
print(b.list()[1]);         // 1
int.wrapping_add(v: int) → int

あふれても止まらない足し算。一周して続きの値になる。

print(1.wrapping_add(2));   // 3
int.wrapping_sub(v: int) → int

あふれても止まらない引き算。

print(5.wrapping_sub(8));   // -3
int.wrapping_mul(v: int) → int

あふれても止まらない掛け算。

print(3.wrapping_mul(4));   // 12
int.compare(other: int) → int

並べ替えのための比較。

print(1.compare(2));   // -1

float

64ビットの小数(IEEE 754)。

int とは混ぜて計算できない。float(n) で変換してから使う。

float.infinity() → float

かぎりなく大きい数。**型の名前から呼ぶ**(`float.infinity()`)。

どんな数より大きく、足しても掛けてもそのまま。「かぎりが無い」ことを表す。 std.ui では、幅・高さの取り分(fr)に渡すと「余りぜんぶ」の意味になる。

var x = float.infinity();
print(x);              // inf
print(x > 1.0e308);    // true
print(x + 1.0 == x);   // true
float.compare(other: float) → int

並べ替えのための比較。

print(1.5.compare(0.5));   // 1

bool

true か false。

if や while の条件に書けるのはこの型だけ。

bool.compare(other: bool) → int

並べ替えのための比較。false が小さい。

print(false.compare(true));   // -1

list<T>

同じ型 T を並べた、長さの変わる配列。

添字は 0 から。範囲外を読むと実行時エラーになる。

list.push(v: T) → void

末尾に足す。

var xs = [1, 2];
xs.push(3);
print(xs.len());   // 3
list.pop() → T?

末尾を取り出して、配列から取り除く。空なら none。

var xs = [1, 2];
print(xs.pop() ?? -1);   // 2
print(xs.len());         // 1
list.len() → int

要素数を返す。

print([1, 2, 3].len());   // 3
list.insert(i: int, v: T) → void

i の位置に差し込む。後ろの要素はずれる。

var xs = ["さめ", "あじ"];
xs.insert(1, "ふぐ");
print(xs[1]);   // ふぐ
list.remove(i: int) → void

i の位置の要素を取り除く。

var xs = [1, 2, 3];
xs.remove(0);
print(xs[0]);   // 2
list.contains(v: T) → bool

その値を含んでいるか。

print([1, 2, 3].contains(2));   // true
list.join(sep: string) → string

区切り文字を挟んで1つの文字列にする。list<string> だけで使える。

print(["さめ", "ふぐ"].join(" と "));   // さめ と ふぐ
list.sort() → void

小さい順に並べ替える。要素が Comparable のときだけ呼べる。

同じ大きさのものは順番が変わらない(安定な並べ替え)。

var xs = [3, 1, 2];
xs.sort();
print(xs[0]);   // 1

map<K, V>

キー K から値 V を引く表。

無いキーを添字で読むと実行時エラー。get() なら none が返る。

map.get(k: K) → V?

引く。無ければ none。

var m = {"さめ": 400};
print(m.get("さめ") ?? 0);   // 400
print(m.get("ふぐ") ?? 0);   // 0
map.has(k: K) → bool

そのキーがあるか。

print({"さめ": 400}.has("さめ"));   // true
map.remove(k: K) → void

そのキーを取り除く。無ければ何もしない。

var m = {"さめ": 400};
m.remove("さめ");
print(m.len());   // 0
map.len() → int

入っている件数を返す。

print({"a": 1, "b": 2}.len());   // 2
map.keys() → list<K>

キーを並べた配列を返す。

var m = {"さめ": 400};
for var k in m.keys() { print(k); }   // さめ
map.values() → list<V>

値を並べた配列を返す。

var m = {"さめ": 400};
print(m.values()[0]);   // 400

Result<T>

成功した値 T か、失敗した Error のどちらか。

失敗するかもしれない関数はこれを返す。try / if var / ?? で取り出す。

Result.ok() → bool

成功しているか。

func half(n: int) -> Result<int> {
  if n % 2 != 0 { return Error("奇数は半分にできません"); }
  return n / 2;
}
print(half(10).ok());   // true
print(half(3).ok());    // false
Result.value() → T

成功した値を取り出す。失敗しているときに呼ぶと panic する。

func half(n: int) -> Result<int> {
  if n % 2 != 0 { return Error("奇数は半分にできません"); }
  return n / 2;
}
var r = half(10);
if r.ok() { print(r.value()); }   // 5
Result.error() → Error

失敗した理由を取り出す。

func half(n: int) -> Result<int> {
  if n % 2 != 0 { return Error("奇数は半分にできません"); }
  return n / 2;
}
var r = half(3);
if !r.ok() { print(r.error().message()); }   // 奇数は半分にできません

Error

失敗の理由。Result に入って返る。

独自のエラーは Error を継承して作り、message() を上書きする。

Error.init(message: string) → void

理由を作る。code を省くと 0 になる。

オーバーロード: Error.init(message: string, code: int) -> void

var e = Error("見つかりません", 404);
print(e.code());   // 404
Error.message() → string

説明の文。

print(Error("見つかりません").message());   // 見つかりません
Error.code() → int

番号。付けていなければ 0。

var e = Error("見つかりません", 404);
print(e.code());   // 404

Comparable

大小を比べられることを表すインタフェース。

これを実装したクラスは、list の sort() で並べ替えられる。

Comparable.compare(other: This) → int

自分と other を比べる。小さいと負、等しいと 0、大きいと正。

class Fish : Comparable {
  public var size: int;
  func init(size: int) { this.size = size; }
  override func compare(other: This) -> int { return this.size - other.size; }
}
var xs = [Fish(400), Fish(20)];
xs.sort();
print(xs[0].size);   // 20