在 Eiffel 中获取错误 "VEVI: Variable is not properly set"

Getting the error "VEVI: Variable is not properly set" in Eiffel

我正在尝试为 Eiffel 中的 linked_list 创建一个迭代器。

我收到此错误:变量设置不正确。

Class: ITERATOR_ON_COLLECTION [E]
Feature: make
Attribute(s): {ITERATOR}.target
Line: 30

我知道这是因为无效安全,但我不知道如何解决。 (我将 void safety 设置为 True 并将预编译库更改为安全版本并 clean_compile 它。)

以下是class:

class
    ITERATOR_ON_COLLECTION [E]

inherit
    ITERATOR [E]

create
    make

feature {NONE} -- Attributes

    collection: LINKED_LIST[E]
    item_index: INTEGER

feature -- initialization

    make(c: LINKED_LIST [E])
        require
            --c /= void
        do
            --  create {COLLECTION} collection.make
            --  create collection.make -- it doesnt work with/without this line 
            collection := c
            item_index := 1
        end

    start
        do
            item_index := 1
        end

    item: STRING
        do
            Result := "hello"
        end

    next
        do
            item_index := item_index + 1
        end

    is_off: BOOLEAN
        do
            Result := True
        end


    do_until (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- and including first one satisfying `test'.
            -- (Apply to full list if no item satisfies `test').
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    do_while (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- and including first one not satisfying `test'.
            -- (Apply to full list if all items satisfy `test').
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    until_do (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- but excluding first one satisfying `test'.
            -- (Apply to full list if no items satisfy `test'.)
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    while_do (action: PROCEDURE [E]; test: FUNCTION [E, BOOLEAN])
            -- Apply `action' to every item of `target' up to
            -- but excluding first one satisfying not `test'.
            -- (Apply to full list if all items satisfy `test'.)
        require else
            action_exists: action /= Void
            test_exists: test /= Void
        do
        end

    there_exists (test: FUNCTION [E, BOOLEAN]): BOOLEAN
            -- Is `test' true for at least one item of `target'?
        require else
            test_exists: test /= Void
        do
        end

    for_all (test: FUNCTION [E, BOOLEAN]): BOOLEAN
            -- Is `test' true for all items of `target'?
        require else
            test_exists: test /= Void
        do
        end

end

如果不查看 class ITERATOR,很难判断真正的原因是什么。这是我的猜测:

Class ITERATOR 声明附加类型的属性 target。该属性必须在您的创建过程中设置。很可能您需要丢弃 class 中的属性 collection 并改用 target。根据属性的类型,您可能需要在 class 中重新定义它。

就努力而言,最好从 classes 的无效安全版本开始,当您从非无效安全设置切换到无效安全设置时,您可能需要确保默认附加 class 类型(在项目设置对话框中查找配置选项 "Are types attached by default?")。此选项应设置为 True(在 16.11 之前的 EiffelStudio 中不会自动完成)。

对代码其他部分的一些评论:

  • 如果附加了参数类型,则没有检查形式 arg /= Void.

  • 如果在父class中为特征指定了先决条件foo,则无需像

    那样重复
    require else
        foo
    

    可以安全删除。 (您可以查看特征平面(或平面短)形式以查看父级的前提条件仍然存在。)

  • 如果重定义特征的注释没有改变,可以替换为

    -- <Precursor>
    

    这样父版本中的任何更改都会自动反映在重新声明中(再次查看平面形式)。