Реальный ответ: вы не можете отменить его на месте, но вы можете создать новую строку, которая является обратным.
Также как упражнение для игры с рекурсией: иногда, когда вы идете в интервью, интервьюер может спросить вас, как это сделать, используя рекурсию, и я думаю, что «предпочтительный ответ» может быть «Я бы предпочел не делать этого в рекурсии, поскольку он может легко вызвать переполнение стека» (поскольку это O(n)
а не O(log n)
.Если это O(log n)
, довольно сложно получить переполнение стека - 4 миллиарда элементов могут обрабатываться уровнем стека 32, так как 2 ** 32 - 4294967296. Но если это O(n)
, тогда он может легко получить переполнение стека.
Иногда интервьюер все еще спрашивает вас: «Как упражнение, почему бы вам не написать его с помощью рекурсии?» И вот он:
String.prototype.reverse = function() {
if (this.length <= 1) return this;
else return this.slice(1).reverse() + this.slice(0,1);
}
тестовый прогон:
var s = "";
for(var i = 0; i < 1000; i++) {
s += ("apple" + i);
}
console.log(s.reverse());
output:
999elppa899elppa...2elppa1elppa0elppa
Чтобы попытаться получить переполнение стека, я сменил 1000
на 10000
в Google Chrome, и он сообщил:
RangeError: Maximum call stack size exceeded
Расширения PHP и PHP построены поверх Zend Engine. Они отображают функциональность Zend Engine для пользователей (PHP-скрипты) и добавляют собственные функции, которые либо доступны для пользователей, либо для других расширений PHP.
Zend Engine предоставляет объектную модель с способ доступа к объектам (функциональность, открытая ArrayAccess
), и общий механизм итерации, используемый для итерации по объектам (idem для Iterator
). Эта объектная модель состоит из нескольких обработчиков, которые PHP и любое расширение могут заменить для типа объекта (обработчики объекта zend ). По своей объектной модели движок Zend реализует стандартный тип объектов («объекты zend»); каждый объект следует за структурой данных zend_object
, и каждый класс - это понятие, которое интерфейс объектов низкого уровня не знает, кроме предоставления способа его извлечения, - zend_class_entry
).
ArrayAccess
на самом деле не является интерфейсом SPL; он определен в самом Zend Engine. Обработчики нижнего уровня read_dimension
/ write_dimension
/ has_dimension
объектов zend реализованы таким образом, что они проверяют, объект реализует такой интерфейс и вызывает соответствующие методы, если это так (см. здесь ).
Iterator
также не является интерфейсом SPL; он также определен в Zend Engine. В этом случае поддержка этого интерфейса выполняется на несколько более высоком уровне. Обработчики объектов низкого уровня ничего не знают об итерации объектов; это свойство объектов Zend. Структура zend_class_entry
содержит два соответствующих элемента: поле iterator_funcs
и поле get_iterator
. Они определяют операции и состояние итератора и как создать новый итератор. Для Iterator
, в частности, когда класс зарегистрирован во время выполнения, он проверяет, реализует ли он этот интерфейс, и если это так, соответствующие поля в переменной zend_class_entry
для этого класса устанавливаются в собственные методы, которые соединяют родные итерационный интерфейс к методам PHP. Если вы пишете PHP-расширение, можно выбрать либо написание собственного итератора (который реализует итерационные методы изначально), либо, как и в пользовательской области, реализовать Iterator
и написать PHP-методы (в этом случае собственные методы PHP ) для нескольких операций, как описывает интерфейс.
Интерфейс Countable
- единственный, который фактически является интерфейсом SPL; Zend Engine ничего об этом не знает. Его функциональность проистекает из того факта, что реализация функции count
проверяет свое присутствие и вызывает метод count
, если интерфейс существует.
Оператор расширения работает при более низкой настройке. Во время выполнения непосредственно записывает в память Zend Engine и заменяет обработчики кодов кода PHP, которые компилируются (так что теперь, например, ZEND_ASSIGN_ADD
имеет новую собственную реализацию, которая отбрасывает некоторые функции / метод PHP, пользователь может выбрать).