在没有明确声明的情况下,还有哪些其他语言支持Go的接口风格?

时间:2013-07-24 16:20:09

标签: c# java interface d type-inference

我是一位经验丰富的爱好程序员,我对C ++,D,Java,C#和其他人非常熟悉。

除了Go之外,几乎所有语言都要求我明确声明我正在实现一个接口。这是荒谬的,因为我们今天拥有像Haskell这样的语言的编译器,它几乎可以用很少的提示进行全程序类型的推断。

我正在寻找的是一种编程语言:

interface ITest {
    void Test();
}

class Test {
    void Test() { }
}

void main() {
    ITest x;
    x = new Test;
}

哪种语言可以看到这一点,并自动将Test标记为实施ITest

ETA :我不是在寻找鸭子打字。我正在寻找带有推断的严格类型语言。

2 个答案:

答案 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 = ...