弱適合:Scala 3で廃止予定の機能(13)

Scala 3.3.1
最終更新:2020年9月20日

[AD] scalapediaでは記事作成ボランティアを募集しています

この記事では、Scala 3で廃止される「弱適合(Weak Conformance)」について解説します。

Scala 3では、Intリテラルは必要に応じて他の数値型に変換される

まず、Scala 3での挙動から説明します。

Intリテラルは、必要に応じて他の数値型に変換されます。

複雑な規則があるのですが、ざっくり言うと「引数リストに、数値型TIntが混ざって渡されている場合」にIntからTへの変換が行われます。

もしFloatByteShortへ変換されると精度が落ちてしまう場合には、変換されずにAnyValに落ち着くことになっています。ご注意ください。

例えば以下で定義される変数listの型はList[Double]となります。

val list = List(5.4, 8, math.abs(-4.0), 0, -0.3)

引数リストにDoubleが3つ、Intが2つ渡されています。

この場合、本来であればIntDoubleの共通のスーパークラスであるAnyValをとってList[AnyVal]となるはずですが、その前にIntDoubleとして扱うことによってList[Double]へと落ち着くわけです。

Scala 2までの「弱適合」は廃止

以前よりScalaを使用している人はご存知かと思いますが、このような変換はもともと存在しています。

実際のところ、Scala 2では、Int以外の数値型に対してもリテラルで記述されているかどうかにかかわらず同様の変換が行われています。
この変換は「弱適合(Weak Conformance)」と呼ばれています。

さて、弱適合にはどのような不都合があったのでしょうか。
それは変換の対象範囲です。

Int以外の数値型に対しても」「リテラルで記述されているかどうかにかかわらず」という言葉から、変換の対象となる範囲がとても広いことがわかります。
これにより意図しない変換が発生しがちだったことから、修正の対象となりました。

例えば、「Int以外の数値型に対しても」ですから、Double, Float, Long, Short, Byte, Charが変換されうることになります。
はい、そうです。まさにお気づきのとおりです。Charも含まれるんです。

CharDoubleに変換されて嬉しいのは相当特殊なケースでしょう。他も同様ですから、必要に応じて明示的に変換するよう変更されて当然ではありますね。

また、「リテラルで記述されているかどうかにかかわらず」ですから、メソッドを実行した戻り値を直接渡していたりしても変換されていました。

こちらは少しわかりづらいですが、その箇所で型についての情報を記述するわけではないので、気を抜くと予期せぬ変換が生じる可能性が出てきます。

3.0へアップデートする前に移行しておく

Scala 3.0には弱適合は実装されませんでした。

したがって、Scala 3.0へのアップデートの前に、弱結合を活用している箇所を修正する必要があります。

外部リンク:Dropped: Weak Conformance

サイト内検索