1. ホーム
  2. scala

なぜ「メソッドのオーバーロードを避ける」のか?

2023-07-29 23:42:52

疑問点

なぜ Jorge Ortiz はメソッドのオーバーロードを避けるように助言していますか?

どのように解決するには?

オーバーロードをすると、メソッドを関数に持ち上げるのが少し難しくなります。

object A {
   def foo(a: Int) = 0
   def foo(b: Boolean) = 0
   def foo(a: Int, b: Int) = 0

   val function = foo _ // fails, must use = foo(_, _) or (a: Int) => foo(a)
}

オーバーロードされたメソッドのセットから1つを選択的にインポートすることはできません。

引数をパラメータ型に適応させるために暗黙のビューを適用しようとすると、あいまいさが生じる可能性が高くなります。

scala> implicit def S2B(s: String) = !s.isEmpty                             
S2B: (s: String)Boolean

scala> implicit def S2I(s: String) = s.length                               
S2I: (s: String)Int

scala> object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }
<console>:15: error: ambiguous reference to overloaded definition,
both method foo in object test of type (b: Boolean)Int
and  method foo in object test of type (a: Int)Int
match argument types (java.lang.String)
       object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }

デフォルトのパラメータを静かに使用不能にすることができます。

object test { 
    def foo(a: Int) = 0; 
    def foo(a: Int, b: Int = 0) = 1 
}

個々には、これらの理由はオーバーロードを完全に敬遠することを強制するものではありません。何か大きな問題を見逃しているような気がします。

アップデイト

証拠は積み重なっている。

アップデイト2

  • パッケージオブジェクトでオーバーロードされたメソッドを使用することは (現在のところ) できません。
  • 適用可能なエラーは 診断が難しい になります。

アップデイト3

  • 静的なオーバーロードの解決は、すべての型安全性のAPIを奪うことができます。
scala> object O { def apply[T](ts: T*) = (); def apply(f: (String => Int)) = () }
defined object O

scala> O((i: String) => f(i)) // oops, I meant to call the second overload but someone changed the return type of `f` when I wasn't looking...