课程的Dlang泛型

Str*_*ers 2 java generics templates d

第一次海报.我已经使用Java几年了,并决定学习D.在Java中,你可以声明一个具有泛型类的类,并从该类创建一个新对象.喜欢:

public class foo<T>
{
    public foo() { ... }
}
Run Code Online (Sandbox Code Playgroud)

然后简单地打电话foo<String> f = new foo<>();.我尝试在D中实现相同的,但我得到了一个编译错误,如:"class core.collection.RingBuffer.RingBuffer(T)用作类型".看一下D的教程,我发现泛型编程是使用模板实现的.但是,我无法正式编写官方教程/文档.有人可以向我解释一下吗?谢谢.

Ada*_*ppe 5

当你没有在右侧实例化模板时会出现这个错误 - 它抱怨"foo被用作一个类型",因为foo本身不是一个类型,它是一个类型的模板.这意味着在用!(arguments)实例化之前它不会成为实际类型.

你的Java代码与new foo<>()D中的代码不完全相同:在D中,你需要在右边给出那里的类型.

所以尝试:

foo!string f = new foo!string();
Run Code Online (Sandbox Code Playgroud)

要么

foo!(string) f = new foo!(string)();
Run Code Online (Sandbox Code Playgroud)

模板参数周围的括号!,如果后面只有一个单词,则是可选的,因此这两个意思相同.

在D中不需要写入两次类型,但是不要将其从右侧移出,而是可以通过类型推断将其留在左侧.这也将编译:

auto f = new foo!string();
Run Code Online (Sandbox Code Playgroud)

这在D中很常见

  • `class foo(T){}`实际上只是`template foo(T){class foo {}}`的简写,`foo!(T)`会自动扩展为`foo!(T).foo`.这可能会让它更加混乱....但规则是模板可以使用模板参数在其中包含任何声明.实例化一个时,除非您指定其他内容,否则将自动选择与模板同名的模板成员.可以使用其他成员,他们只是更私密.这两个事实相结合意味着模板类与模板相同,其中只有一个类. (2认同)

Gas*_*ssa 5

这是一个使用泛型的简约 Java 代码:

class Foo <T>
{
    public Foo (String arg) {System.out.println ("Hello, " + arg + "!");}
}

public class TestClass
{
    public static void main (String [] args)
    {
        Foo <String> f = new Foo <> ("Alice");
        Foo <String> g = new Foo <String> ("Bob");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是它的 D 等价物:

import std.stdio;

class Foo (T)
{
    public this (string arg) {writeln ("Hello, " ~ arg ~ "!");}
}

void main ()
{
    auto f = new Foo !(string) ("Alice");
    Foo !(string) g = new Foo !(string) ("Bob");
}
Run Code Online (Sandbox Code Playgroud)

这些只是完整的可编译示例。推理在Adam D. Ruppe 的回答中进行了解释