Scala: Method overloading over generic types

前端 未结 3 1319
夕颜
夕颜 2020-12-31 11:12

In C# I can overload methods on generic type as shown in the example below:

// http://ideone.com/QVooD
using System;
using System.Collections.Generic;

publ         


        
相关标签:
3条回答
  • 2020-12-31 11:28

    Kinda hackish, and both methods need the same return type (here: Unit)...

    def fooInt(list: List[Int]) = println("int")
    def fooDouble(list: List[Double]) = println("double")
    
    def foo[N <: AnyVal](list:List[N])(implicit m:ClassManifest[N]) = m.erasure match {
        case c if c == classOf[Int] => fooInt(list.asInstanceOf[List[Int]])
        case c if c == classOf[Double] => fooDouble(list.asInstanceOf[List[Double]])
        case _ => error("No soup for you!")
    }
    
    foo(List(1,2,3,4))
    //--> int
    
    foo(List(1.0,2.0,3.0))
    //--> double
    
    0 讨论(0)
  • 2020-12-31 11:43

    The Manifest won't really help either becuase those will have the same type after erasure.

    What will help having different numbers of arguments (or different types after erasure). I find having different numbers of implicit arguments can transparently solve this problem, and by using scala.Predef.DummyImplicit, you don't even have to import an implicit anywhere.

    class Test{
      def foo(ints : List[Int])
      def foo(doubles : List[Double])(implicit i1:DummyImplicit)
      def foo(strings : List[String])(implicit i1:DummyImplicit, i2:DummyImplicit)
    }
    
    0 讨论(0)
  • 2020-12-31 11:43

    You would not do it like that in Scala. Why try to emulate something that can never work properly given JVM restrictions? Try idiomatic Scala instead:

    trait Fooable[T] {
      def foo : Unit
    }
    
    object IntListFoo extends Fooable[List[Int]] {
      def foo {
        println("I just print")
      }
    }
    
    class DoubleListFoo(val l : List[Double]) extends Fooable[List[Double]] {
      def foo {
        println("I iterate over list and print it.")
        l.foreach { e =>
          println(e)
        }
      }
    }
    
    implicit def intlist2fooable(l : List[Int]) = IntListFoo
    implicit def doublelist2fooable(l : List[Double]) = new DoubleListFoo(l)
    

    Then, you can execute code like

    List(1,2,3,4).foo
    List(1.0,2.0,3.0).foo
    
    0 讨论(0)
提交回复
热议问题