string和std.file的意外行为

时间:2014-06-08 19:13:51

标签: d dmd

我有以下代码块,它在DMD v2.063.2

上干净地编译
import std.stdio;
import std.string;
import std.file;

void main(string[] args)
{
    auto file = File("a_file.txt", "rb");

    string line;
    string source;

    while ((line = file.readln()) !is null)
    {
        source.append(line);
    }

    writeln("--- source: ---");
    writeln(source);
    writeln("---------------");
}

但是,每次运行时都会发生以下错误:

std.file.FileException@std/file.d(386): : No such file or directory
----------------
5   test                                0x000000010b955c9e void std.file.writeImpl(const(char[]), const(void[]), const(uint)) + 142
6   test                                0x000000010b955c08 void std.file.append(const(char[]), const(void[])) + 56
7   test                                0x000000010b92787e _Dmain + 174
8   test                                0x000000010b94330d extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain() + 33
9   test                                0x000000010b942e59 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate()) + 45
10  test                                0x000000010b943359 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll() + 61
11  test                                0x000000010b942e59 extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate()) + 45
12  test                                0x000000010b942e0d _d_run_main + 457
13  test                                0x000000010b942c3c main + 20
14  libdyld.dylib                       0x00007fff9a7de5fd start + 1
15  ???                                 0x0000000000000001 0x0 + 1
----------------

我对错误感到困惑,因为该文件存在并且显然已被打开。错误消息完全是误导性的。我已设法将错误指向while()循环体中的行source.append(line);

当我偶然看一下string类型的文档时,发现它没有append方法。然后,查看std.file的文档,我发现有一个全局append函数。那么错误信息就有意义了。

所以看起来编译器以某种方式设法在std.file.append字符串对象上调用source(我们可以在异常调用堆栈中观察到),从而导致这个非常棘手的错误。这怎么可能呢?谁能解释一下这个问题?

请原谅我,如果我在这里缺少一些基本的语言点,我是初学者,但这似乎彻底打破了类型安全的想法,不是吗?

2 个答案:

答案 0 :(得分:2)

您正在查看UFCS的实际操作。你可能没想到它,但我不知道它是如何打破类型安全的。但是,异常消息可能会使用无法找到的文件。喜欢"没有这样的文件或目录:filename.ext"。

答案 1 :(得分:1)

使用phobos!

 import std.array, std.stdio;

 string source = file.byLine.join.idup;