Haskell相当于下面的代码会产生正确的答案吗?
可以修复此Scala代码以生成正确的答案吗?如果有,怎么样?
object TypeErasurePatternMatchQuestion extends App {
val li=List(1,2,3)
val ls=List("1","2","3")
val si=Set(1,2,3)
val ss=Set("1","2","3")
def whatIsIt(o:Any)=o match{
case o:List[Int] => "List[Int]"
case o:List[String] => "List[String]"
case o:Set[Int] => "Set[Int]"
case o:Set[String] => "Set[String]"
}
println(whatIsIt(li))
println(whatIsIt(ls))
println(whatIsIt(si))
println(whatIsIt(ss))
}
Run Code Online (Sandbox Code Playgroud)
打印:
List[Int]
List[Int]
Set[Int]
Set[Int]
Run Code Online (Sandbox Code Playgroud)
但我希望它能打印出来:
List[Int]
List[String]
Set[Int]
Set[String]
Run Code Online (Sandbox Code Playgroud) public void run(){
setFont("Courier-24");
//Define list as ArrayList<Integer>
ArrayList<Integer> list = new ArrayList<Integer>();
readList(list);
}
private void readList(ArrayList list){
list.add("Hello");
list.add(2);
println("list = "+list);
println("Type of list = "+list.get(0).getClass());
println("Type of list = "+list.get(1).getClass());
}
Run Code Online (Sandbox Code Playgroud)
结果:
list = [Hello,2]
list的类型= class java.lang.String
list的类型= class java.lang.Integer
这是我的代码和结果.我的问题是,Integer类型的ArrayList如何可以存储String对象?现在列表的类型是什么?这是什么机制?
乍一看,我认为以下是有道理的:
interface Test<T> {
T getValue(T n);
}
class Impl implements Test<Integer>{
public Integer getValue(Integer n){
return n;
}
}
Run Code Online (Sandbox Code Playgroud)
它编译正确,所以一切看起来都很好。
但是后来我在擦除的上下文中考虑了更多,在我看来,Test 接口被擦除为:
interface Test {
Object getValue(Object n);
}
Run Code Online (Sandbox Code Playgroud)
那么 Impl 怎么还能实现 Test 呢?
以下代码提供编译错误,错误"重复方法"
static int test(int i){
return 1;
}
static String test(int i){
return "abc";
}
Run Code Online (Sandbox Code Playgroud)
这是预期的,因为重载方法具有相同的签名并且仅在返回类型方面不同.
但是下面的代码编译好了警告:
static int test1(List<Integer> l){
return 1;
}
static String test1(List<String> l){
return "abc";
}
Run Code Online (Sandbox Code Playgroud)
因为,我们知道Java Generics在Erasure上运行,这意味着在字节码中,这两种方法都具有完全相同的签名,并且与返回类型不同.
更令我惊讶的是,以下代码再次出现编译错误:
static int test1(List<Integer> l){
return 1;
}
static String test1(List l){
return "abc";
}
Run Code Online (Sandbox Code Playgroud)
如果有重复的方法,第二个代码如何工作正常而不会给出任何编译错误?
我有一些代码如下:
public class java_generic {
public static void main(String[] args) {
T t = new X();
t.<Object>m(new Object());
t.<String>m(new String());
}
static class T {
<E> void m (E e){
System.out.println("here is T");
}
}
static class X extends T {
void m (String o){
System.out.println("here is X");
}
}
}
Run Code Online (Sandbox Code Playgroud)
从我的理解,在类型擦除后,课程T将成为这样:
static class T {
void m (Object e){
System.out.println("here is T");
}
}
Run Code Online (Sandbox Code Playgroud)
并且m超载.
有m(Object)和m(String),我希望结果会是
here is T
here is X
Run Code Online (Sandbox Code Playgroud)
但结果是 …
所以说我们有几个这样的类:
abstract class Throw {
def winsOver(t2: Throw): Boolean
}
class Rock extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Scissors => true
case _ => false
}
}
class Scissors extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Paper => true
case _ => false
}
}
class Paper extends Throw {
override def winsOver(t2: Throw): Boolean = t2 match {
case _: Rock => true
case …Run Code Online (Sandbox Code Playgroud) lazy val productService = BeanLookup [ProductDataService]
object BeanLookup {
def apply[T](implicit manifest: Manifest[T], context: ActorContext) = {
val beanLookup =
context.actorFor("/user/spring/beanLookup")
Await.result(
(beanLookup.ask(LookupBean(manifest.erasure))(timeout)).mapTo[T](manifest),
timeout.duration) }
def apply[T](implicit manifest: Manifest[T], system: ActorSystem) = {
val beanLookup =
system.actorFor("/user/spring/beanLookup")
Await.result(
(beanLookup.ask(LookupBean(manifest.erasure))(timeout)).mapTo[T](manifest),
timeout.duration) } }
Run Code Online (Sandbox Code Playgroud)
scalac抱怨:
scala: ambiguous reference to overloaded definition,
both method apply in object BeanLookup of type (implicit manifest: Manifest[com.tooe.core.service.LocationCategoryDataService], implicit system: akka.actor.ActorSystem)com.tooe.core.service.LocationCategoryDataService
and method apply in object BeanLookup of type (implicit manifest: Manifest[com.tooe.core.service.LocationCategoryDataService], implicit context: akka.actor.ActorContext)com.tooe.core.service.LocationCategoryDataService
Run Code Online (Sandbox Code Playgroud) case class Thing[T](value: T)
def processThing(thing: Thing[_]) = {
thing match {
case Thing(value: Int) => "Thing of int"
case Thing(value: String) => "Thing of string"
case _ => "Thing of something else"
}
}
println(processThing(Thing(1)))
println(processThing(Thing("hello")))
Run Code Online (Sandbox Code Playgroud)
以上输出Thing of int和Thing of string. 我的问题是,如果类型橡皮擦启动,为什么类型信息在运行时仍然可用?
erasure ×8
generics ×4
java ×4
scala ×4
type-erasure ×3
types ×3
overloading ×2
arraylist ×1
haskell ×1
implicit ×1