You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何声明File.byLine()赋值的变量类型?结构体模板推导报错

解决D语言ThingReader结构体的成员类型声明问题

看起来你卡在了结构体成员类型的声明和模板实例化推导上,我来一步步帮你解决:

核心问题拆解

你遇到的几个问题本质是:

  1. D语言的结构体成员不能直接用auto声明(除非是较新版本的D支持的特性);
  2. 模板结构体实例化时,编译器不会自动推导模板参数;
  3. 直接写ByLine报错是因为它是模板类型,需要指定参数或正确导入。

具体解决方案

方案1:用模板结构体+显式推导/工厂函数(最通用)

你的模板结构体思路是正确的,只是实例化方式不对。D的结构体不会自动推导模板参数,我们可以用两种方式解决:

方法A:显式指定模板参数

实例化时,用typeof(f.byLine)获取byLine返回的实际类型:

// 你的模板结构体保持不变
struct ThingReader(Lines) {
    Lines lines;
    Thing thing;

    this(File f) {
        this.lines = f.byLine;
        popFront;
    }

    @property bool empty() { return lines.empty; }
    @property ref Thing front() { return thing; }
    void popFront() {
        if (!empty) {
            auto l = lines.front;
            lines.popFront;
            parseLine(l, thing); // 假设parseLine已实现
        }
    }
}

// 实例化方式
auto reader = ThingReader!(typeof(f.byLine))(f);

方法B:添加静态工厂函数简化使用

为了避免每次都写typeof(f.byLine),可以给结构体加一个静态工厂方法,让编译器自动推导模板参数:

struct ThingReader(Lines) {
    Lines lines;
    Thing thing;

    this(File f) {
        this.lines = f.byLine;
        popFront;
    }

    // 其他方法和之前一样...

    // 静态工厂函数,自动推导Lines类型
    static auto create(File f) {
        return ThingReader!(typeof(f.byLine))(f);
    }
}

// 使用方式更简洁
auto reader = ThingReader.create(f);

方案2:直接声明完整的ByLine类型(非模板方案)

如果你不想用模板,需要明确写出byLine返回的完整类型。首先确保导入std.stdio,然后指定ByLine的模板参数(默认是char类型的字符和换行符):

import std.stdio;

struct ThingReader {
    // 完整的类型声明
    std.stdio.ByLine!(char, char) lines;
    Thing thing;

    this(File f) {
        this.lines = f.byLine;
        popFront;
    }

    // 其他方法不变
}

不过这个方式灵活性差——如果后续你调用f.byLine!(wchar)或者byLine(keepTerminator: true),类型会变化,模板方案更适配这种场景。

方案3:利用D 2.081+的auto成员推导(最简单)

从D 2.081版本开始,结构体成员支持auto声明,只要在构造器中完成初始化,编译器会自动推导类型:

struct ThingReader {
    auto lines; // D 2.081及以上版本支持
    Thing thing;

    this(File f) {
        this.lines = f.byLine;
        popFront;
    }

    // 其他方法不变
}

// 直接实例化即可
auto reader = ThingReader(f);

这个方式最省心,但要注意你的编译器版本是否达标。

为什么之前写ByLine会报错?

你之前尝试ByLine或std.stdio.ByLine报错,是因为ByLine是一个模板类型,必须指定模板参数才能使用(比如ByLine!(char, char)),或者通过typeof(f.byLine)让编译器帮你推导完整类型。

内容的提问来源于stack exchange,提问作者neniu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:15:27