我是一位经验丰富的爱好程序员,我对C ++,D,Java,C#和其他人非常熟悉。
除了Go之外,几乎所有语言都要求我明确声明我正在实现一个接口。这是荒谬的,因为我们今天拥有像Haskell这样的语言的编译器,它几乎可以用很少的提示进行全程序类型的推断。
我正在寻找的是一种编程语言:
interface ITest {
void Test();
}
class Test {
void Test() { }
}
void main() {
ITest x;
x = new Test;
}
哪种语言可以看到这一点,并自动将Test
标记为实施ITest
?
ETA :我不是在寻找鸭子打字。我正在寻找带有推断的严格类型语言。
答案 0 :(得分:12)
D在其标准库Phobos中有一个名为wrap
的东西,可以做你正在寻找的东西。以下是从函数单元测试中复制的示例:
interface A {
int run();
}
interface B {
int stop();
@property int status();
}
class X {
int run() {
return 1;
}
int stop() {
return 2;
}
@property int status() {
return 3;
}
}
auto x = new X();
auto ab = x.wrap!(A, B);
A a = ab;
B b = ab;
assert(a.run() == 1);
assert(b.stop() == 2);
assert(b.status == 3);
这项工作将从v2.064开始提供,它已经在git HEAD上了。
答案 1 :(得分:0)
实际上,任何动态语言(javascript,python等)都支持这种模式。但我猜你对那些静态验证该类型满足相关接口的语言感兴趣。
C ++
这种支持并不完全是您所要求的,因为您不会直接使用ITest
。相反,您将使用一个模板,只需访问所需类型
// C# style solution
void UseIt(ITest p) {
p.Test();
}
// C++ style solution
template <typename T>
void UseIt(T p) {
p.Test();
}
C ++ UseIt
方法适用于任何具有可访问成员Test
的类型。这里不需要界面
class C1 {
public:
void Test() { }
}
class C2 { }
UseIt<C1>(C1()); // Ok
UseIt<C2>(C2()); // Error!
<强>打字稿强>
Typescript直接实现您描述的模式。在一天结束时,打字稿只是javascript的一个薄包装,因此是动态的。但它确实提供了编译时类型注释。它对接口的支持与您在问题中描述的模式完全匹配
<强> F#强>
F#通过内联声明的成员约束对C ++提供类似的支持
let inline UseIt<^T when ^T : (member Test: unit -> unit)> s = ...