Groovy 闭包委派未委派给子对象

Groovy closure delegation not delegating to child objects

提问人:Mike Warren 提问时间:9/21/2022 更新时间:9/22/2022 访问量:43

问:

我有这个代码,用于处理数据源电子表格的两个单独的工作表。我有一些专门用于处理电子表格本身的。它包含方法BaseRecordHandler

    protected void initDataSourceFile() throws IOException {
        File file = new File(this.dataSourceFilename);
        this.excelFile = this.getWorkbook(file);

        if (file.exists())
            return;

        file.getParentFile().mkdirs();

        FileOutputStream outputStream = new FileOutputStream(file);

        this.setupSpreadsheet({ Sheet sheet ->
            setupFirstRow(sheet.createRow(0));

            sheet.createFreezePane(0, 1);

            // returning the sheet allows for the functional programming technique known as composition
            return sheet;
        });

        this.excelFile.write(outputStream);
        outputStream.close();
        this.excelFile.close();
    }

实际的电子表格处理程序(称为)有两个子 s。其定义为:PracticeProfileHandlerBaseSheetHandlersetupSpreadsheet()

    @Override
    protected void setupSpreadsheet(Closure<Sheet> onSetupSheet) {

        Closure onGetAndSetupSheet = SMDSpreadsheetUtils.OnCreateIfNotExistSheet(this.excelFile) >> onSetupSheet;

        this.childPracticeURLHandler = new PracticeURLHandler(onGetAndSetupSheet);
        this.childOrgNameHandler = new OrganizationNameHandler(onGetAndSetupSheet);
    }

    @Override
    protected void setupFirstRow(Row firstRow) {
        throw new Exception("PracticeProfileHandler should not be trying to set up the first row of a Sheet");
    }

BaseSheetHandler定义如下:

public abstract class BaseSheetHandler<T> {
    protected Sheet sheet;
    protected List<T> usedRecords;

    protected BaseSheetHandler(Closure<Sheet> onGetSheet) {
        onGetSheet.setDelegate(this);
        this.sheet = onGetSheet(this.getSheetName());
        this.init();
    }

    // ...rest of code...
}

子处理程序在其各自的类上实现。fillInRow()

问题是,当我击中这个时,它表现得好像子实例不存在,而是击中了那个,尽管我将包含该行代码的回调委托给子实例本身(通过构造函数)!practiceProfileHandler.initDataSourceFile()fillInRow()PracticeProfileHandlerBaseSheetHandler

是什么导致了这种情况,我该如何解决?

Groovy 委托 闭包

评论

0赞 emilles 9/21/2022
如果基类是静态编译的,则缺少指示解析策略的 DelegatesTo 批注。在您设置委托时,我认为您是在说您希望首先检查委托。所以你还应该设置ResolveStrategy(DELEGATE_FIRST)
0赞 emilles 9/21/2022
您始终可以在调用点单步执行 invokeMethod,以查看运行时如何选择方法目标。

答:

0赞 Mike Warren 9/22/2022 #1

根据@emilles建议,我在构造函数中设置了解析策略:BaseSheetHandler

    protected BaseSheetHandler(Closure<Sheet> onGetSheet) {
        onGetSheet.setResolveStrategy(Closure.DELEGATE_FIRST);
        onGetSheet.setDelegate(this);
        this.sheet = onGetSheet(this.getSheetName());
        this.init();
    }

它有效!

我应该把它写在一些闭包 utils 类上......!