Java/C#类型系统有哪些不足之处?

Cam*_*pka 6 c# java haskell type-systems

它经常听说Haskell(我不知道)有一个非常有趣的类型系统.我对Java非常熟悉,而且对C#有点熟悉,有时我会对类型系统进行战斗,所以有些设计适应或以某种方式更好地工作.

这让我想知道......

由于Java/C#类型系统的不足,以某种方式出现了什么问题?你是如何处理它们的?

ega*_*aga 8

阵列坏了.

  Object[] foo = new String[1];
  foo[0] = new Integer(4);
Run Code Online (Sandbox Code Playgroud)

给你java.lang.ArrayStoreException

你谨慎对待它们.

可空性是另一个大问题.NullPointerExceptions随处可见.除了切换语言之外,你真的无法对它们做任何事情,或者尽可能使用避免它们的惯例(正确初始化字段等).

更一般地说,Java/C#的类型系统不是很有表现力.Haskell可以给你的最重要的事情是,通过它的类型你可以强制执行这些函数没有副作用.编译时证明部分程序只是被评估的表达式,使程序更可靠,可组合,更容易推理.(忽略这一事实,Haskell的实现为您提供了绕过它的方法).

与Java相比,调用方法几乎可以做任何事情!

Haskell也有模式匹配,它为您提供了创建程序的不同方式; 你有关于哪些函数运行的数据,通常是递归的.在模式匹配中,您可以破坏数据以查看它是什么类型,并根据它进行操作.例如,你有一个列表,它可以是空的,也可以是头尾.如果要计算长度,可以定义一个函数:如果list为空,则length = 0,否则length = 1 + length(tail).

如果您真的想了解更多,那么有两个优秀的在线资源:

了解Haskell真实世界Haskell

  • 不.类型系统的要点是它不应该编译. (10认同)

Dar*_*rio 5

我不喜欢的事实,那就是原始(原生)类型之间的差异(int,boolean,double和它们对应的类包装() ,Integer,Boolean)Double在Java中.

这通常非常烦人,特别是在编写通用代码时.本机类型不能通用化,您必须实例化一个包装器.泛型应该使您的代码更抽象,更容易重用,但在Java中,它们带来了限制,显然没有理由.

private static <T> T First(T arg[]) {
    return arg[0];
}

public static void main(String[] args) {        
    int x[] = {1, 2, 3};
    Integer y[] = {3, 4, 5};

    First(x); // Wrong
    First(y); // Fine
}
Run Code Online (Sandbox Code Playgroud)

在.NET中,即使存在单独的值和引用类型,也没有这样的问题,因为它们严格意识到"一切都是对象".


pgb*_*pgb 2

我不喜欢这样的事实:类不是一流的对象,并且您不能做一些花哨的事情,例如将静态方法作为接口的一部分。