named parameterとnamed argument
void f( int x, [ int y = 0, int z = 0 ] ) { }
void main()
{
f( 0 ) ; // f( 0, 0, 0 )
f( 0, 1 ) ; // f( 0, 1, 0 )
f( 0, z : 1 ) ; // f( 0, 0, 1 )
}
まあ、コードを読めば一目瞭然の機能だろう。省略可能なのは、named parameterだけである。名前を指定できるのも、named parameterだけである。normalFormalParameterは省略も名前指定もできない。
noSuchMethod
class X
{
void noSuchMethod( String function_name, List args )
{
print("$function_name") ;
for ( var elem in args )
{ print("$elem") ; }
}
}
void main()
{
X x = new X() ;
// 関数名と実引数が表示される
x.f() ;
x.hoge(1,2,3,4,5) ;
x.fuga("All base is belong to us.")
}
これは解説が必要だろう。もし、クラスからメソッド名のlookupに失敗した場合、そのクラスからnoSuchMethodという名前のインスタンスメソッドが探され、第一引数としてメソッド名を、第二引数として、実引数のリストを渡し、呼び出されるのだ。もし、noSuchMethodという名前のインスタンスメソッドがなければ、NoSuchMethodExceptionが投げられる。
ということはだ、noSuchMethodというインスタンスメソッドを定義していれば、あたかもoperator .を定義したかのように振る舞うのだ。もちろん、実際にはoperator .はないし、メソッド呼び出しにしか適用できないが、DSLオタクは歓喜するだろう。
typedef
typedef int func_type(int) ;
void f( func_type func )
{
int x = func( 0 ) ;
}
main()
{
f( (int x) => x + 1 ) ;
}
typedefは、静的型の別名を定義するための構文である。現在のところ、関数の静的型の別名を定義することしかできない。
これはなぜかというと、関数は、具体的な静的型を直接に指定するのは面倒なのだ。こんなふうになってしまう。
void f( int func(int) ) { }
インターフェースFunctionはあるが、あまりにアバウトすぎる。だから、厳密な静的型を意味する識別子を定義するために、このtypedefが存在する。
べつに、これを使う必要はない。たとえば、varで受けても問題ない。DartはOptional Typeを採用しているからだ。静的型は実行時には、ほとんど意味がない。
No comments:
Post a Comment