Uva をはじめようかなー

www.adventar.org

エントリーポイント

Uva は決まったエントリーポイントを持たない言語です。
例えば、クラスの外においては Java は一切の文あるいは式(クラス・インターフェイス定義、import 文、package 文を除く)を書くことが許されていませんが、 Uva では許されています。
なので、println( "Hello, World!" );main() の外に書いても構いません。

shared のこと

shared というのは一見キーワードのように見えますが、実のところアノテーションの 1 つです。
shared が付いた関数や変数、クラスなどはこのソースコードの外からでも見えるようになります。
つまり、可視性を司るアノテーションです。

ループ

Uva にはループは for-inwhileuntil の 3 つがあります。
for-in は以下のような、C# でいう foreach の形をもつ for 文です。

for ( auto i in 1..5 ) {
    for ( auto j in 1..j ) {
        print( "*" );
    }
    println();
}

標準出力への出力

標準出力に出力する方法の 1 つとして、println() があります。
これは、何らかの値を出力し、最後に改行を出力するという関数です。

ちなみに、最後に改行を出力しない同じような関数として print() があります。

print()println() はそれぞれ、process.stdout.print()process.stdout.println()エイリアスです。

process オブジェクト

process はビルトインの現在のプロセスを表すオブジェクトです。

    variable String? input = process.readLine();

null 許容型

process.readLine() の戻り値は String? です(おそらく)。
String? の後ろの方の ?null が入っているかもしれない String 型という意味です。
String? を別の表記(複合型表記)で表すと String|Null です。

Null 型の唯 1 つのオブジェクトが null です。

    if ( exists input ) {
        String[] tokens = input.split();
        int?[] numbers   = tokens.map( int.parse );
    }

例えば int.parse() は整数値にパースできない文字列が渡された場合、null を返します。
このようなメソッドないしは関数の戻り値型は ? 付きです。

is

ある型 Tnull 許容型 T? の値が null かどうかを確かめる 1 つの方法が is 式を使うことです。
is 式は右オペランドの値が左オペランドの型あるいは左オペランドの型を継承した型である場合、真を返します。

if-exists ガード句

もう 1 つの方法が if-exists ガード句を使う方法です。

Hoge? hoge = getHogeOrNull();

if ( exists hoge ) {
    // このブロックでは hoge は Hoge 型であることが明確になる。
    println( "it's Hoge" );
} else {
    // このブロックでは hoge が null であることが確実。
    println( "it's null" );
}