Error code: VUTA(3) Error: separate target of the Object_call is not controlled

Error code: VUTA(3) Error: separate target of the Object_call is not controlled

我是 Eiffel 的完全初学者,我正在实施链表作为练习。我在功能 has 中收到以下错误(告诉您列表是否包含 v)。

Error code: VUTA(3)

Error: separate target of the Object_call is not controlled.
What to do: ensure the target of the call is controlled or is not separate.

Class: MY_LINKED_LIST [G]
Feature: has
Type: Generic #1
Line: 159
          then
->          if l_cursor_a.item.is_equal (v) then
              Result := True

奇怪的是,当我将“.is_equal”更改为“=”时,错误消失了。我不知道错误描述中的 'controlled' 是什么意思,也不知道在这种情况下使用“=”有什么区别。代码如下:

MY_LINKED_LIST[G]

class
    MY_LINKED_LIST[G]

feature -- Access

    item: G
        require
            not off
        do
            check
                off: attached cursor as l_cursor
            then
                Result := l_cursor.item
            end
        end

    first,
    last: detachable like item


feature -- Measurement

    count: INTEGER

feature -- Element change


feature -- Status report

    index: INTEGER

    before: BOOLEAN

    after: BOOLEAN

    has (v: like item): BOOLEAN
        require

        local
            l_cursor: like cursor
        do
            from
                l_cursor := first_element
            until
                not attached l_cursor or Result
            loop
                check
                    attached l_cursor as l_cursor_a
                then
                    if l_cursor_a.item.is_equal (v) then
                        Result := True
                    end
                    l_cursor := l_cursor_a.next
                end
            end
        ensure
            function_not_change_state: item = old item
        end


feature {NONE} -- Implementation

    cursor,
    first_element,
    last_element: detachable MY_CELL[G]


end -- class

MY_CELL[G]

class
    MY_CELL[G]

feature -- Access

    item: G

该错误消息与 SCOOP 有关——Eiffel 内置的并发编程模型。根据它,只有当对象 controlled 时,才能在 separate 对象上调用功能。当调用的目标是一个特征的参数时,或者当使用特殊的 单独指令 时,就可以实现这一点。在你的情况下,后者看起来像

separate l_cursor_a.item as x do
    if x.is_equal (v) then
         Result := True
    end
end

为什么 l_cursor_a.item 首先被认为是独立的?它有一个类型 G,并且正式的泛型是不受约束的,与具有约束 detachable separate ANY 相同(因此,上面的代码很可能无法编译,您需要确保 x 在调用 is_equal 之前附加。

相等运算符=不执行任何调用(除非涉及的类型被扩展,但扩展的类型永远不会分开)。对于引用类型(包括单独的),它只是简单地测试两个引用是否相同。这解释了为什么将 is_equal 替换为 = 时错误消失的原因。

避免错误消息的另一种解决方案是将形式泛型的约束更改为非分离:MY_LINKED_LIST [G -> detachable ANY]

旁注。 检查指令 check attached l_cursor as l_cursor_a then ... 似乎是多余的,编译器应该能够自动找出附加的 l_cursor