型エラーの検出
◦ 関数の戻り値の型は intでなければいけない
◦ ところが、引数の $b が float なので $c は int + float = float である
◦ というわけで、戻り値の型が正しくないと文句を言っている
2014/05/02 社内勉強会資料 28
$ vi test.hh
<?hh
function add_error(int $a, float $b): int {
$c = $a + $b;
return $c;
}
$ hh_client check
/.../test.hh:4:10,11: Invalid return type
/.../test.hh:2:39,41: This is an int
/.../test.hh:2:28,32: It is incompatible with a float
29.
型エラーの修正
◦ intval 関数を入れることで$c の型が int になった
◦ 単に int にキャストする方法でも同じ
2014/05/02 社内勉強会資料 29
$ vi test.hh
<?hh
function add_error_fixed(int $a, float $b): int {
$c = intval($a + $b);
return $c;
}
$ hh_client check
No errors!
30.
Nullable
◦ 型の先頭に ?を書くと null 許容型になる
このプログラムには型エラーがあります (次のスライドで説明)
2014/05/02 社内勉強会資料 30
$ vi test.hh
<?hh
function add_null(?int $a, int $b): int {
$c = $a + $b;
return $c;
}
31.
Nullable (型エラーの検出)
◦ $aは算術演算子 “+” で使われるので int か float でなければいけない
◦ ところが $a は null 許容型である
◦ というわけで、型のエラーだと文句を言っている
2014/05/02 社内勉強会資料 31
<?hh
function add_null(?int $a, int $b): int {
$c = $a + $b;
return $c;
}
$ hh_client check
/.../test.hh:3:8,9: Typing error
/.../test.hh:3:8,9: This is a num (int/float) because
this is used in an arithmetic operation
/.../test.hh:2:19,22: It is incompatible with a nullable
type
32.
Nullable (型エラーの修正)
◦ nullのときは 0 を代入することで、演算の箇所での $a は int になった
◦ 三項演算子を使って書いても同じ
2014/05/02 社内勉強会資料 32
$ vi test.hh
<?hh
function add_null(?int $a, int $b): int {
if ($a == null) {
$a = 0;
}
$c = $a + $b;
return $c;
}
$ hh_client check
No errors!
Type Aliasing
◦ 右辺のデータ型に左辺の別名を付ける
◦プログラムが分かりやすくなる
2014/05/02 社内勉強会資料 36
$ vi test.hh
<?hh
type point = shape('x' => int, 'y' => int);
function new_point(int $x, int $y) : point {
return shape('x' => $x, 'y' => $y);
}
function get_x(point $p) : int { return $p['x']; }
function get_y(point $p) : int { return $p['y']; }
37.
Type Aliasing (newtype)
◦newtype を使うと、ファイルの外側からは右辺が見えなくなる
◦ プログラムのモジュール化に役立つ
2014/05/02 社内勉強会資料 37
$ vi test.hh
<?hh
newtype point = shape('x' => int, 'y' => int);
function new_point(int $x, int $y) : point {
return shape('x' => $x, 'y' => $y);
}
function get_x(point $p) : int { return $p['x']; }
function get_y(point $p) : int { return $p['y']; }
38.
Type Aliasing (型エラーの検出)
◦point の実体が shape(‘x’ => int, …) だということは隠されている
◦ というわけで、$p はコンテナではなく point だと文句を言っている
2014/05/02 社内勉強会資料 38
<?hh
require 'test.hh';
function main() : void {
$p = new_point(1, 2);
$p['x'] = 3;
}
$ hh_client check
/.../main.hh:6:3,9: This is not a container, this is an
object of type point
/.../main.hh:5:38,42: You might want to check this out
hh_client と HHVM
HHVMでは実行開始時に型検査するわけではない
◦ 関数の先頭で仮引数と実引数の型が合致しているか検査
◦ 関数を抜けるときに戻り値の型が合致しているか検査
hh_client がエラーにするコードも HHVM では実行できる
2014/05/02 社内勉強会資料 40
$ cat type_error.hh
<?hh
function test($cond): int { return $cond ? 1 : 'foo'; }
print test($argv[1]) . "¥n";
$ hhvm type_error.hh 1
1
$ hhvm type_error.hh 0
Fatal error: Value returned from test() must be of type
int, string given in /.../type_error.hh on line 3