d - 如何在 D 中的 @safe 函数中执行 I/O?

标签 d

我正在学习 D 编程语言,并且我试图将自己限制在它的 SafeD 子集中。但是,我注意到像 writeln 这样的 I/O 函数都是@system。我如何在 SafeD 中进行 I/O?

我在 Fedora 19 x86-64 上使用 LDC2(从 Fedora 包下载)。

最佳答案

你没有,或者至少不是直接的。 I/O 需要进行系统调用,这意味着 C 函数,而 C 函数不会是 @safe .自从writeln目前调用printf在引擎盖下,它绝对不会是 @safe , 因为用 printf 做不安全的事情是微不足道的(比如给它%s,然后给它一个整数而不是一个字符串)。有可能使writeln @trusted在某些情况下,但我不知道这会涉及什么。这将取决于它是如何实现的。

任何非平凡的 D 程序都将使用 @system代码。诀窍是隔离它。您的程序的大部分内容有望是 @safe , 但它的部分必须是 @system .但是,您只需检查程序的一小部分以确保内存安全。一旦您手动验证调用 @system 的函数函数实际上是内存安全的,您可以将其标记为 @trusted然后你可以在 @safe 中使用它代码。

不幸的是,druntime 和 Phobos 中的某些核心内容也很可能是 @system。基于它对低级东西所做的事情,不一定所有这些都被标记为 @trusted应该是这样(例如 std.array.appender 可能是 @system 而它可能应该是 @trusted - 我不确定它目前是什么;它可能取决于数组的元素类型)。所以,为了更好地支持 @safe,可能需要对一些标准库的东西进行一些改进。 (正在进行中,但我不知道现在所有这些都在哪里),您最终可能不得不使用 @trusted现在在比你将来更多的地方。 writeln可能是也可能不是@safe@trusted在将来。但是,如果您使用的类型没有 @safe,则绝对不会。或 @trusted toString功能,所以部分是否 writeln@safe取决于您使用它的方式,无论它是如何实现的。但是,目前不是 @safe@trusted即使使用内置类型,所以现在,你不走运。

如果你真的想要,你可以为 writeln 创建一个包装器。这是@trusted ,但是您必须非常小心,以确保代码实际上是内存安全的 - 并且只需创建一个模板包装器并将其标记为 @trusted不会削减它,因为那样你就会把它当作 @safe不管你传递给它什么类型。因此,最好不要包装它,然后将调用者标记为 @trusted如果您确定 writeln 的特殊用途是内存安全的。当然,这也突出了为什么像 writeln 这样的函数的部分原因。目前是 @system首先:通常很难写@trusted模板化代码不信任不应信任的东西(因为它取决于模板参数)。属性推断通常会解决这个问题,但如果模板代码正在做一些需要 @trusted 的事情, 将代码的一部分标记为 @trusted 变得很困难剩下的留给推理,尤其是当模板参数与 @system 混合在一起时东西。不过,我希望我们最终会对所有标准库的内容进行整理。

关于d - 如何在 D 中的 @safe 函数中执行 I/O?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19101305/

相关文章:

module - D中单独模块中类的静态初始化和使用

d - mixin 到 D 中的每个非抽象子类中

windows - 使用 GUI 创建 Windows 程序但使用 'main()'(在 D 中)?

d - D 中的切片交集

json - 如何在 D 中使用 JSON 数据发出 http POST 请求

templates - 返回不同输入范围时函数返回类型不匹配的现象

d - 具有相同类型参数的可变参数模板函数

size - 为什么D程序可执行文件大到几乎9+ MiB?

d - vibe.d 的 Diet 模板中的别名是什么?

c - DMD:链接到 libc.a?或者 core.simd 信息?