已经一个方法被提出来处理的重载方法双定义是,以取代与模式匹配超载:
object Bar {
def foo(xs: Any*) = xs foreach {
case _:String => println("str")
case _:Int => println("int")
case _ => throw new UglyRuntimeException()
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法要求我们放弃对参数的静态类型检查foo.能够写作会好得多
object Bar {
def foo(xs: (String or Int)*) = xs foreach {
case _: String => println("str")
case _: Int => println("int")
}
}
Run Code Online (Sandbox Code Playgroud)
我可以接近Either,但它有两种以上的快速变得难看:
type or[L,R] = Either[L,R]
implicit def l2Or[L,R](l: L): L or R = Left(l)
implicit def r2Or[L,R](r: R): L or R = …Run Code Online (Sandbox Code Playgroud) 我在scala中写了这个,它不会编译:
class TestDoubleDef{
def foo(p:List[String]) = {}
def foo(p:List[Int]) = {}
}
Run Code Online (Sandbox Code Playgroud)
编译通知:
[error] double definition:
[error] method foo:(List[String])Unit and
[error] method foo:(List[Int])Unit at line 120
[error] have same type after erasure: (List)Unit
Run Code Online (Sandbox Code Playgroud)
我知道JVM没有对泛型的原生支持,所以我理解这个错误.
我可以写包装List[String],List[Int]但我很懒:)
我很怀疑,但是,有没有另一种方式表达List[String]不是同一种类型List[Int]?
谢谢.
在C#中,我可以重载泛型类型的方法,如下例所示:
// http://ideone.com/QVooD
using System;
using System.Collections.Generic;
public class Test {
public static void Foo(List<int> ints) {
Console.WriteLine("I just print");
}
public static void Foo(List<double> doubles) {
Console.WriteLine("I iterate over list and print it.");
foreach(var x in doubles)
Console.WriteLine(x);
}
public static void Main(string[] args) {
Foo(new List<int> {1, 2});
Foo(new List<double> {3.4, 1.2});
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试在Scala中执行相同操作,则会引发编译时错误,List[Int]并List[Double]由于擦除而擦除到相同类型.我听说Scala Manifest可以用来解决这个问题,但我不知道怎么做.我也没有在文档中找到任何有用的东西.
所以我的问题是:我如何使用Manifests(或其他任何有效的方法)重载方法而不是因擦除而擦除到相同类型的泛型类型?
scala ×4
overloading ×2
compilation ×1
generics ×1
manifest ×1
reification ×1
type-erasure ×1
typeclass ×1