在我学习Haskell的过程中,我注意到它的类型类,它应该是一个源自Haskell的伟大发明.
但是,在类型类的维基百科页面中:
程序员通过指定一组函数或常量名称以及它们各自的类型来定义类型类,这些类型必须存在于属于该类的每个类型.
这似乎与Java的界面非常接近(引用维基百科的界面(Java)页面):
Java编程语言中的接口是一种抽象类型,用于指定类必须实现的接口(在术语的一般意义上).
这两个看起来很相似:类型类限制了类型的行为,而接口限制了类的行为.
我想知道Haskell中的类类和Java中的接口之间有什么区别和相似之处,或者它们可能根本不同?
编辑:我注意到即使haskell.org也承认它们是相似的.如果它们如此相似(或者它们是什么?),那么为什么类型类会受到这样的炒作?
更多编辑:哇,这么多很棒的答案!我想我必须让社区决定哪个是最好的.然而,在阅读答案时,所有人似乎都只是说"在界面无法或不得不应对泛型时,类节目可以做很多事情".我不禁想知道,有什么接口可以做而类型不能吗?此外,我注意到维基百科声称类型类最初是在1989年的论文中发明的*"如何使ad-hoc多态性不那么特别",而Haskell仍处于摇篮之中,而Java项目始于1991年并于1995年首次发布那么也许代码类似于接口,而另一种方式,接口受类型类的影响?是否有任何文件/文件支持或反驳?感谢所有答案,他们都非常有启发性!
感谢所有的投入!
我最近在学习Java,我遇到了package-private
类的概念,如果我们没有指定任何东西,这是默认的.但后来我意识到:
我很少看到使用package-private类.是否有这样的原因,例如,它有严重的缺点,它是多余的,或者只是我阅读不够?是否有强烈的论据支持/反对其使用?
如果它在大多数情况下确实没用,为什么它会是默认值?
在什么情况下我们应该在现实世界中使用package-private?即,什么时候会变得不可替代?
换句话说,默认的package-private修饰符的主要优点和缺点是什么?
我知道当我们在另一个模板中使用模板时,我们应该这样写:
vector<pair<int,int> > s;
如果我们在没有空格的情况下写它:
vector<pair<int,int>> s;
我们会收到一个错误:
嵌套模板参数列表中的`>>'应该是`>>'
我觉得这是可以理解的,但我不禁想知道,在哪种情况下,这真的很模糊?
今天我偶然定义了一个二维数组,其中一维的大小为0,但是我的编译器没有抱怨.我发现以下内容表明这是合法的,至少在gcc的情况下:
但是,我对这个用法有两个问题:
首先,这被认为是良好的编程习惯吗?如果是这样,那么我们何时应该在现实世界中使用它?
其次,我定义的数组是二维的,一维的0大小.这和一维情况一样吗?例如,
int s[0]
int s[0][100]
int s[100][0]
Run Code Online (Sandbox Code Playgroud)
它们在内存和编译器中都是一样的吗?
编辑:回复Greg:我使用的编译器是gcc 4.4.5.我对这个问题的意图不依赖于编译器,但是如果有任何编译器特定的怪癖也会有用:)
提前致谢!
据说当输入参数为null时,compareTo()应抛出NullPointerException.但是,我正在实现一个需要将字段与String类型进行比较的类.这些字段不必是强制性的.我想知道在这种情况下,
1)当输入为空时我应该返回什么?任何非空字符串在字典上是大于还是小于null?
和
2)如果这被认为是不好的做法,是否有任何支持性论点?我应该强制用户使用空字符串吗?如果使用空字符串,那不会混淆字段不适用的情况和字段为空的情况吗?如果必须抛出异常,那么除了在手册中警告用户之外,我还能做什么?
编辑:我可能不会在这里清楚地表达自己,但在我正在实现的程序中,可以为null的字符串是所有字段或类,它们不应为null.换句话说,comparisonTo()使用的对象不能为null,只有它们的私有字段可以.所以在这种情况下,我相信如果我正确地实现了compareTo(),它就不会违反传递要求,因为具有空字段的类总是被认为是相同的.我是对的还是我在解释这个错误?
谢谢大家的答案!
Java 1.5 的Java序列化规范说:
对于可序列化对象,运行第一个非可序列化超类型的no-arg构造函数.对于可序列化的类,字段将初始化为适合其类型的默认值.然后通过调用类特定的readObject方法来恢复每个类的字段,或者如果没有定义它们,则通过调用defaultReadObject方法来恢复.请注意,在反序列化期间,不会对可序列化类执行字段初始值设定项和构造函数.
但是,这意味着如果我们在类中放置一个静态变量(例如计数器变量),它将不会像通常那样更新:
class Foo {
static int t;
public Foo() {
t++;
}
}
public class Bar extends Foo implements Serializable {
static int t;
public Bar() {
t++;
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果一个实例Bar
被反序列化,那么计数器Foo
是正确的,计数器Bar
是一个一个.
我想知道为什么反序列化不会调用构造函数?由于看起来虽然这会在速度上获得一点点,但它可能会导致潜在的问题.编译器可以很容易地设计为生成一个"静态构造函数",它只更新将要更新的静态变量,并且在加载类时不依赖于外部信息.
另外,我想知道避免这种情况的最佳方法是什么?我能想到的解决方案是使用静态变量上的操作打包反序列化.
感谢提前输入!
我正在cabal install glib-0.12.3
使用cabal-install 0.10.2在我的Ubuntu 11.10下尝试.但是,它显示以下错误消息:
setup: The program gtk2hsC2hs version >=0.13.5 is required but the version
found at /usr/bin/gtk2hsC2hs is version 0.13.4
cabal: Error: some packages failed to install:
glib-0.12.3 failed during the configure step. The exception was:
ExitFailure 1
Run Code Online (Sandbox Code Playgroud)
经过半个小时的搜索,我无法找到它的gtk2hsC2hs
位置.我挖到像http://code.haskell.org/gtk2hs/tools/c2hs/这样的地方,但似乎找不到合适的版本.
我怎么能升级我的gtk2hsC2hs?谢谢!
使用Eclipse将项目导出为Runnable JAR文件时,有三种选择:
1. Extract required libraries into generated JAR
2. Package required libraries into generated JAR
3. Copy required libraries into a sub-folder next to the generated JAR
Run Code Online (Sandbox Code Playgroud)
但是,似乎只能从Runnable JAR File Export窗口中选择三个选项中的一个.我想知道是否有一些方法可以混淆这些方法,例如,在打包其余文件的同时提取一些文件?
注意:我需要这个,因为我的一个JAR文件包含大量对其他文件的引用,所以1不能是一个选项,我担心2可能会给我带来一些问题.
谢谢!
在Java中,do-while
循环体和循环条件不属于同一范围.所以下面的代码将无法编译:
do {
boolean b = false;
} while (b); // b cannot be resolved to a variable
Run Code Online (Sandbox Code Playgroud)
但是这段代码对我有意义.
而且,如果身体和状况在同一范围内,我找不到任何陷阱; 由于正文将始终执行,而Java没有Goto
,我不知道如何do-while
跳过最外层体范围中的变量声明.即使有可能,编译器也总能检测到这种可能性,然后产生编译时错误.
这种行为是否有任何原因(除了保持do-while
循环的格式相同while
)?我很好奇.感谢您的任何投入!
我太困了以至于我编写了以下代码(修改后只显示了混乱):
fac s = take 10 [s, s `mod` 1 ..]
maxFactor x = if (s == [])
then x
else head <-- this should be 'head x' instead of just 'head'
where s = fac x
Run Code Online (Sandbox Code Playgroud)
但是,这个加载到ghci(和编译)就好了.当我执行时maxFactor 1
,它抱怨(当然):
<interactive>:0:1:
No instance for (Integral ([a0] -> a0))
arising from a use of `maxFactor'
Possible fix:
add an instance declaration for (Integral ([a0] -> a0))
In the expression: maxFactor 1
In an equation for `it': it = maxFactor 1 …
Run Code Online (Sandbox Code Playgroud)