2014-06-08 17 views
3

我有下面的代码块,这对DMD v2.063.2完全编译用绳子意外行为和std.file

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("---------------"); 
} 

但是,每次运行时,这种错误发生:

[email protected]/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。错误消息然后是有道理的。

所以它看起来像编译器设法在source字符串对象上调用std.file.append(正如我们可以在异常调用堆栈中观察到的那样),从而导致这个非常棘手的错误。这怎么可能?任何人都可以解释一下这个问题吗?

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

回答

2

您正在看到UFCS正在运行。你可能没有预料到它,但我不明白它是如何打破类型安全。但是,例外消息可能会使用提及的文件,但无法找到。像“没有这样的文件或目录:filename.ext”。

+0

因此,编译器实际上是重新排列行'追加(源线);'...是的,在这种情况下,似乎是没有类型的冲突出现,因为'source'是一个字符串和第二个参数是一个'void []'。但相当可怕的错误,我认为你会同意。 – glampert

1

使用phobos!

import std.array, std.stdio; 

string source = file.byLine.join.idup; 
+0

所以如果我明白了,那会将'file'的每一行复制到'source'字符串中,对吗?有效地做while循环。很高兴知道,谢谢!但对于我的具体情况,我需要测试每一行寻找给定的字符串。如果字符串存在,那么我需要替换它,否则按原样添加该行。 – glampert