d的静态类

原文
Java/C#中,可创建纯类.
这些的方法都是的,不能继承或实例化类:

static class Algo {
    void drawLine(Canvas c, Pos from, Pos to) { ...... };
}

使用类:

Algo.drawLine(new Canvas(), new Pos(5, 3), new Pos(7, 9));

在D中是不可能的,这很差.解决办法似乎是:

final abstract class Algo {
    void drawLine(Canvas c, Pos from, Pos to) { ...... };
}

在D中无法实现该功能.final表示不能扩展类,abstract不能实例化自己.然而,与JavaC#不同,不实例化所述就不能调用函数,因为函数在类对象上工作.
此外,还有关键字,但可按外部类成员实例化静类.
D不是Java,也永远不会是,如果想要类似功能,可把函数放进单独文件中,然后在文件顶部加一行:

module modulename;

并命叫modulename.d.然后,可按java中的.class文件用此模块,方法是添加

import modulename;

使用它的文件.
此外,还有各种导入选项,如重命名或静导入(不给模块加域,因此不需要全名)

静导入,可用来模拟名字空间,更复杂的是创建包含公开导入的模块来组合内容,但这在D中并不常见.静导入

static import std.stdio;

void main()
{
 //否,不会解析此函数,编译错误
  // wrtiteln("hello");
  // 好
  std.stdio.writeln("hello");
}

有两个方法,一个是私实现:

module drawer.impl;
void drawLine(...)

然后,创建另一个文件:

module drawer;
public import Algo = drawer.impl;

之后,可按Algo.drawLine使用.
使用单文件,可如下:

final class Algo
{
    @disable this();
static:
    void drawLine(...){}
}

上面也是可行的,但与Java不同,在Java中,每个类都有自己的文件.
静方法就是这样.
如果要禁止创建类,用@disable this();,如果要使所有方法都是的,请把静:(static:)放在类顶上.
注意,此时变成了名字空间,也可用模板,尽管它可能有点难看:

template Algo_ns()
{
   void drawLine(Canvas c, Pos from, Pos to) {...}
}

// 需要这样才能避免`实例化语法`
alias Algo = Algo_ns!();

但,浪费了类的其他功能(生成typeinfo,添加到类型系统等),因此模板不会这样做.

但是为什么不把drawLine搞成自由函数呢?

import bluepandastuff.algo;
auto canvas = new Canvas();
drawLine(canvas, Pos(5, 3), Pos(7, 9));
// 或用UFCS:
canvas.drawLine(Pos(5, 3), Pos(7, 9));

我把Pos转换成了典型值类型的结构.
没错.

void Algo_drawLine(Canvas c, Pos from, Pos to) { ...... };
posted @ 2023-01-21 10:22  zjh6  阅读(24)  评论(0)    收藏  举报  来源