На абстрактном уровне вы можете включить все, что захотите, в язык, который вы разрабатываете.
На уровне реализации неизбежно, что некоторые из этих вещей будут проще для реализации, некоторые будут сложными, некоторые могут быть сделаны быстро, некоторые обязательно будут медленнее и так далее. Чтобы объяснить это, дизайнерам часто приходится принимать сложные решения и идти на компромиссы.
На уровне реализации одним из самых быстрых способов доступа к переменной является определение ее адреса и загрузка содержимого этого адреса. В большинстве процессоров есть специальные инструкции для загрузки данных с адресов, и эти инструкции обычно должны знать, сколько байтов им нужно загрузить (один, два, четыре, восемь и т. Д.) И куда поместить загружаемые данные (один регистр, регистр). пара, расширенный регистр, другая память и т. д.). Зная размер переменной, компилятор может точно знать, какую инструкцию использовать для использования этой переменной. Не зная размера переменной, компилятору придется прибегнуть к чему-то более сложному и, возможно, более медленному.
На абстрактном уровне смыслом подтипирования является возможность использовать экземпляры одного типа, где ожидается одинаковый или более общий тип. Другими словами, может быть написан код, который ожидает объект определенного типа или что-то более производное, не зная заранее, что именно это будет. И, разумеется, поскольку большее количество производных типов может добавлять больше элементов данных, производный тип не обязательно имеет те же требования к памяти, что и его базовые типы.
На уровне реализации нет простого способа для переменной заранее определенного размера, чтобы хранить экземпляр неизвестного размера и быть доступным способом, который вы обычно называете эффективным. Но есть способ немного изменить положение вещей и использовать переменную не для хранения объекта, а для идентификации объекта и сохранения этого объекта в другом месте. Таким способом является ссылка (например, адрес памяти) - дополнительный уровень косвенности, который гарантирует, что переменная должна содержать только некоторую информацию фиксированного размера, при условии, что мы можем найти объект через эту информацию. Чтобы достичь этого, нам просто нужно загрузить адрес (фиксированного размера), а затем мы можем работать как обычно, используя те смещения объекта, которые, как мы знаем, действительны, даже если этот объект имеет больше данных с смещениями, которые мы не знаем. Мы можем сделать это, потому что мы не
На абстрактном уровне этот метод позволяет сохранять (ссылку на a) string
в object
переменной, не теряя информацию, которая делает ее a string
. Это нормально для всех типов, и вы также можете сказать, что это элегантно во многих отношениях.
Тем не менее, на уровне реализации дополнительный уровень косвенности включает в себя больше инструкций и на большинстве архитектур делает каждый доступ к объекту несколько медленнее. Вы можете позволить компилятору выжать из программы больше производительности, если вы включите в свой язык некоторые часто используемые типы, которые не имеют такого дополнительного уровня косвенности (ссылка). Но, удалив этот уровень косвенности, компилятор не может позволить вам выполнять подтипы безопасным способом памяти. Это связано с тем, что если вы добавите больше элементов данных к своему типу и назначите более общий тип, любые дополнительные элементы данных, которые не помещаются в пространство, выделенное для целевой переменной, будут вырезаны.