【问题标题】:What other languages support Go's style of interfacing without explicit declaration?还有哪些其他语言支持 Go 的接口风格而无需显式声明?
【发布时间】:2013-07-24 16:20:08
【问题描述】:

我是一个经验丰富的业余程序员,我熟悉 C++、D、Java、C# 等。

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

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

interface ITest {
    void Test();
}

class Test {
    void Test() { }
}

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

哪些语言会看到这一点,并自动将Test 标记为实现ITest?

ETA:我不是在寻找鸭子打字。我正在寻找具有推理功能的严格类型语言。

【问题讨论】:

  • JavaScript 算不算?您可以在任何拥有它的对象上调用Test() 函数,而无需声明接口。
  • 我不确定这个问题是否适合 SO。如果你想拥有一份具有 Go 惊人特性的语言列表,也许programmers.se 会更好。
  • 您是否正在寻找任何使用鸭式打字的语言? JS、Python、Ruby 等?

标签: c# java interface d type-inference


【解决方案1】:

D 在其标准库 Phobos 中有一个名为 wrap 的东西,它可以满足您的需求。这是从函数的 unittest 复制的示例:

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 上。

【讨论】:

【解决方案2】:

几乎所有的动态语言(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

Typescript 直接实现了您描述的模式。归根结底,打字稿只是 javascript 的一个薄包装器,因此是动态的。但它确实提供了编译时类型注释。它对接口的支持与您在问题中描述的模式完全匹配

F#

F# 通过对内联声明的成员约束提供与 C++ 类似的支持

let inline UseIt<^T when ^T : (member Test: unit -> unit)> s = ...

【讨论】:

  • 是的,D在这方面与C++类似。
  • @AdamD.Ruppe 我认为 D 是,但我没有足够的经验来明智地评论它
  • 这不是我想要的:模板/遗传解决方案具有(除非编译器非常聪明)关联的多个机器代码序列,而接口解决方案通常只有一个(取决于接口表查找)。
  • @KarlDamgaardAsmussen C++ 模板将导致直接调用相关方法。这应该总是比接口调度更少的指令。
  • 但它会为每种类型创建不同的函数,导致一些代码膨胀。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-08
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多