【问题标题】:Unexpected behaviour with string and std.file字符串和 std.file 的意外行为
【发布时间】:2014-06-08 19:13:51
【问题描述】:

我有以下代码块,可以在 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函数。那么错误消息是有道理的。

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

如果我在这里遗漏了语言的一些基本点,请原谅我,我是初学者,但这似乎完全打破了类型安全的概念,不是吗?

【问题讨论】:

    标签: d dmd


    【解决方案1】:

    您正在看到UFCS 在行动。您可能没有预料到它,但我看不出它是如何破坏类型安全的。不过,异常消息可能会提及无法找到的文件。比如“没有这样的文件或目录:filename.ext”。

    【讨论】:

    • 所以编译器实际上正在将行重新排列为append(source, line);...是的,在这种情况下似乎没有类型冲突,因为source是一个字符串,第二个参数是一个void[]。但我想你会同意的。
    【解决方案2】:

    使用火卫一!

     import std.array, std.stdio;
    
     string source = file.byLine.join.idup;
    

    【讨论】:

    • 所以如果我理解的话,这会将“文件”的每一行复制到“源”字符串中,对吗?有效地做while循环所做的事情。很高兴知道,谢谢!但对于我的具体情况,我需要测试每一行以查找给定的字符串。如果字符串存在,那么我需要替换它,否则按原样附加该行。
    猜你喜欢
    • 2014-08-07
    • 2021-06-13
    • 2023-03-26
    • 2018-06-22
    • 1970-01-01
    • 2014-03-18
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多