Eiffel: ошибка компиляции `Источник назначения не совместим с целью` - PullRequest
0 голосов
/ 27 сентября 2018

С полной проверкой пустоты, установленной в компиляторе, у меня есть Переменная неправильно установлена ​​ошибка компиляции в следующем случае, что для меня правильно (на мой взгляд).Это говорит о том, что источник назначения не совместим с целью.Что мне здесь не хватает ???(DB_SERVICE.load_from_primary_key...)

enter image description here

Класс DB_SERVICE

deferred class
    DB_SERVICE [G -> DB_ENTITY create make_from_db_result end]

inherit
    ACTION
        redefine
            start,
            execute
        end

    LOGGABLE
        rename
            make as make_from_loggable
        end

feature -- Creation

    make (a_db_connection: attached DB_CONNECTION)
        require
            valid_db_connection: a_db_connection.is_connected
        do
            make_from_loggable
            db_connection := a_db_connection
            create last_items.make (100)
            create last_column_names.make_empty
        ensure
            db_connection_setted: a_db_connection = db_connection and db_connection.is_connected
        end

feature -- Access

    item: detachable G

    db_connection: DB_CONNECTION

    last_items: HASH_TABLE[like item, INTEGER] -- content of last resultset

    last_column_names: ARRAY[STRING] -- Column names of last resultset

feature -- status_report


    load_from_primary_key (primary_key: INTEGER)
            -- Loads given item into item otherwise item will be Void
        require
            attached db_connection.base_selection
        local
            l_db_result: DB_RESULT
        do
            if attached db_connection.base_selection as bs then
                bs.query ("SELECT * FROM " + ({attached like item}).out + " WHERE " + {attached like item}.Primary_key_db_column_name + "=" + primary_key.out)
                if bs.is_ok then
                    bs.load_result
                    create item.make_from_db_result(last_column_names, bs.cursor)
                else
                    item := Void --HERE is the compiler complaining!
                    logger.write_critical ("Error while retreiving " + ({like item}).out + " from DB")
                end
            else
                item := Void 
                logger.write_error ("base_selection is void")
            end
        end


end -- class

Класс COMPANY_SERVICE

class
    COMPANY_SERVICE

inherit
    DB_SERVICE[COMPANY]
        redefine
            make
        end
...

Класс COMPANY

class
    COMPANY

inherit
    DB_ENTITY
        rename
            primary_key as id,
            set_primary_key as set_id,
            Primary_key_db_column_name as Id_db_column_name
        redefine
            make,
            make_from_db_result,
            out
        end

create
    make,
    make_from_db_result

....

1 Ответ

0 голосов
/ 28 сентября 2018

Объявление типа detachable G указывает, что если соответствующий фактический универсальный тип является ссылочным типом, переменная этого типа может быть отсоединяемой.В этом случае было бы хорошо назначить Void такой переменной.Тем не менее, также возможно, что фактический универсальный является расширенным типом.Префикс расширенного типа с detachable не имеет никакого эффекта, тип остается тем же самым, и переменная не может быть назначена Void.

В качестве примера, давайте рассмотрим более простой случай, когда нет формального общего ограничениядля параметра G.Фактическим обобщением может быть STRING, а переменная item имеет тип detachable STRING.В этом случае можно присвоить Void для item.

Теперь, если фактическим универсальным значением является INTEGER, переменная имеет тип detachable INTEGER, который эквивалентен INTEGER.Присвоение Void переменной этого типа не имеет смысла и не разрешено правилами языка.

Переменная item все еще может быть установлена ​​в Void, если фактический универсальный параметр является ссылочным типом,Для этого может быть объявлена ​​локальная переменная с таким же типом, и ее значение может быть присвоено item:

local
    default_item: like item
do
    item := default_item
...