java中的Lisp Interpreter,处理泛型

时间:2018-04-16 03:53:42

标签: java generics

我正在用Java编写一个Lisp解释器,而且我对语言中的泛化性有点担心。我有一个类List,其定义如下:

public class List<E extends Lisp> implements Lisp {

    private ArrayList<E> list = new ArrayList<>();

    List(){
    /* Constructor code goes here */
    }

    /*
    Other methods that deal with lists go here
    */

}

Lisp只是一个接口,我用它作为Lisp,Atoms和Lists中两种类型的共同点。由于Lisp中的列表可以指向更多列表以及Atoms,因此我需要能够通过通用性将列表存储到列表中,这意味着ArrayList需要能够保存类型为{{1}的对象}和List类型的对象。当我尝试提取列表的第一个成员时出现问题,理论上它可以是列表或原子,但我可以拥有两个具有相同名称并返回不同类型的函数。因此,我想到的解决方法是:

Atom

我的想法是,如果存储的对象是public E car(List<E> l) { if (l.list.get(0) instanceof Atom) return (E)(Atom) l.list.get(0); else return (E)(List<E>) l.list.get(0); } 类型,将其转换为Atom然后再转换为通用对象E,是否有其他方法解决此问题?

另一个问题是,在方法Atom中,重载时有两个定义,一个看起来像这样:

cons

和另一个看起来像这样:

public List<E> cons(List<E> l1, List<E> l2) 

口译员/编制者似乎认为 public List<E> cons(Atom a, List<E> l) { List<E> cons_list = new List<E>(); cons_list.list.add(a); cons_list.list.addAll(l.list); return cons_list; } 不包括E。有没有解决这个问题? eclipse报告的错误是:

  

类型ArrayList中的方法add(E)不适用于   参数(Atom)

1 个答案:

答案 0 :(得分:2)

  

解释器/编译器似乎认为E不包括Atom。有没有解决这个问题?

在编译时,您的程序无意知道EAtom。必须通过另一个类测试才能使它工作:

public List<E> cons(E a, List<E> l) {
    List<E> cons_list = new List<E>();

    if (a instanceof Atom)    {
        cons_list.list.add(a);
    }

    cons_list.list.addAll(l.list);

    return cons_list;
}

这可以解决您的问题,因为您尝试将E对象添加到List<E>

  

我的想法是,如果存储的对象是Atom类型,将其转换为Atom然后转换为通用对象E,还有其他方法解决此问题吗?

您的断言是正确的。这与我之前所说的问题相同:如果你试图将其强制转换为Atom,那么只有你的编译器才会让你运行你的程序。但是,我认为你的演员选择是没用的:你有一个通用的对象,但是你在测试类时知道它是Atom。我想你可以像这样减少你的方法:

public E car(List<E> l) {

    if (l.list.get(0) instanceof Atom)
        // Your `E` is an Atom, you know this when coming then
        // Your list contains E's, so you don't have to cast it
        return l.list.get(0);
    else
        // Here you need the double cast, because you don't try
        // the actual class: it may be anything.
        return (E)(List<E>) l.list.get(0);
}

另外,请注意ClassCastException语句else。您可以尝试使用List<E>,尽管可以确定它可以是ListAtom