Jump to content

это (компьютерное программирование)

(Перенаправлено из Открытой рекурсии )

this , self и Me ключевые слова, используемые в некоторых языках программирования для обозначения объекта, класса или другого объекта, частью которого является текущий выполняющийся код. Таким образом, упомянутая сущность зависит от контекста выполнения (например, от того, у какого объекта вызывается метод). В разных языках программирования эти ключевые слова используются несколько по-разному. В языках, где ключевое слово типа «this» является обязательным, это ключевое слово — единственный способ получить доступ к данным и методам, хранящимся в текущем объекте. Если это необязательно, эти ключевые слова могут устранить неоднозначность переменных и функций с одинаковыми именами.

Объектно-ориентированное программирование

[ редактировать ]

Во многих объектно-ориентированных языках программирования this (также называемый self или Me) — это переменная, которая используется в методах экземпляра для ссылки на объект, над которым они работают. Первый объектно-ориентированный язык, SIMULA 67 , использовался this для явной ссылки на локальный объект. [1] : 4.3.2.3  C++ и языки, стили которых унаследованы от него (такие как Java , C# , D и PHP ), также обычно используют this. Smalltalk и другие, такие как Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex и Swift , используют self. Microsoft Visual Basic использует Me.

Эта концепция одинакова на всех языках: this обычно является неизменяемой ссылкой или указателем , который ссылается на текущий объект; текущий объект часто является кодом, который действует как «родительский» или «вызывающий» для свойства , метода , подпрограммы или функции, содержащей this ключевое слово. После того, как объект правильно сконструирован или создан экземпляр, this всегда является допустимой ссылкой. Некоторые языки требуют этого явно; другие используют лексическую область видимости , чтобы неявно использовать ее для отображения символов внутри своего класса. Или, альтернативно, текущий объект, на который ссылается this может быть независимым объектом кода, вызвавшим функцию или метод, содержащий ключевое слово this. Подобное происходит, например, когда обработчик событий JavaScript , прикрепленный к тегу HTML на веб-странице, вызывает функцию, содержащую ключевое слово this хранится в глобальном пространстве вне объекта документа; в этом контексте, this будет ссылаться на элемент страницы внутри объекта документа, а не на включающий его объект окна. [2]

В некоторых языках, например C++, Java и Raku. this или self является ключевым словом , и переменная автоматически существует в методах экземпляра. В других, например Python, Rust и Perl 5, такой ссылкой является первый параметр метода экземпляра. Это необходимо указать явно. В Python и Perl параметру не обязательно присваивать имя. this или self; Программист может свободно называть его, как и любой другой параметр. Однако по неофициальному соглашению первый параметр метода экземпляра в Perl или Python называется self. Rust требует вызова объекта self &self или self, в зависимости от того, заимствует ли вызываемая функция вызывающий объект или перемещает его соответственно.

Статические методы в C++ или Java связаны не с экземплярами, а с классами, и поэтому не могут использовать this, потому что объекта нет. В других языках, таких как Ruby, Smalltalk, Objective-C или Swift, метод связан с объектом класса , который передается как thisи они называются методами класса . Для методов класса Python использует cls для доступа к объекту класса .

Тонкости и сложности

[ редактировать ]

Когда лексическая область видимости используется для вывода this, использование this в коде, хотя и не является незаконным, может стать сигналом тревоги для программиста по сопровождению, хотя все еще существуют законные варианты использования this в этом случае, например, ссылка на переменные экземпляра, скрытые локальными переменными с тем же именем, или если метод хочет вернуть ссылку на текущий объект, т.е. this, сам.

В некоторых компиляторах (например, GCC ) указатели на методы экземпляра C++ могут быть напрямую приведены к указателю другого типа с явным this параметр указателя. [3]

Открытая рекурсия

[ редактировать ]

Семантика отправки this, а именно этот метод вызывает this динамически отправляются, называется открытой рекурсией и означает, что эти методы могут быть переопределены производными классами или объектами. Напротив, прямая именованная рекурсия или анонимная рекурсия функции использует закрытую рекурсию с ранним связыванием. Например, в следующем коде Perl для факториала токен __SUB__ является ссылкой на текущую функцию:

use feature ":5.16";
sub {
    my $x = shift;
    $x == 0 ? 1 : $x * __SUB__->( $x - 1 );
}

Напротив, в C++ (с использованием явного this для ясности, хотя и не обязательно) this привязывается к самому объекту, но если метод класса был объявлен «виртуальным», то есть полиморфным в базе, он разрешается посредством динамической отправки ( позднего связывания ), чтобы производные классы могли его переопределить.

unsigned int factorial(unsigned int n)
{
  if (n == 0)
    return 1;
  else
    return n * this->factorial(n - 1);
}

Этот пример искусственный, поскольку это прямая рекурсия, поэтому переопределение factorial метод переопределит эту функцию; более естественными примерами являются случаи, когда метод производного класса вызывает тот же метод базового класса или в случаях взаимной рекурсии. [4] [5]

В проблеме хрупкого базового класса обвиняют открытую рекурсию, предполагая, что вызов методов this по умолчанию используется закрытая рекурсия (статическая диспетчеризация, раннее связывание), а не открытая рекурсия (динамическая диспетчеризация, позднее связывание), открытая рекурсия используется только тогда, когда это специально запрошено; внешние вызовы (без использования this) будет динамически отправляться, как обычно. [6] [7] На практике в JDK эта проблема решается посредством определенной дисциплины программиста; эта дисциплина была формализована К. Руби и Г. Т. Ливенсом; он состоит из следующих правил: [8]

  • Ни один код не вызывает public методы на this.
  • Код, который можно повторно использовать внутри страны (путем вызова других методов того же класса), инкапсулируется в protected или private метод; если его также необходимо предоставить непосредственно пользователям, тогда оболочка public метод вызывает внутренний метод.
  • Предыдущую рекомендацию можно смягчить для чистых методов.

Реализации

[ редактировать ]

Ранние версии C++ позволяли this указатель изменить; таким образом программист мог изменить объект, над которым работал метод. Эта функция со временем была удалена, и теперь this в C++ — это r-значение . [9]

Ранние версии C++ не включали ссылки, и было высказано предположение, что если бы они были такими в C++ с самого начала, this была бы ссылкой, а не указателем. [10]

C++ позволяет объектам уничтожать себя с помощью оператора исходного кода: delete this.

Ключевое слово this в C# для ссылочных типов работает так же, как и в Java. Однако в типах значений C # this имеет совершенно другую семантику, похож на обычную ссылку на изменяемую переменную и может даже встречаться в левой части присваивания.

Одно использование this в C# — разрешить ссылку на переменную внешнего поля внутри метода, который содержит локальную переменную с тем же именем. В такой ситуации, например, утверждение var n = localAndFieldname; внутри метода будет присвоен тип и значение локальной переменной localAndFieldname к n, тогда как утверждение var n = this.localAndFieldname; назначит тип и значение переменной внешнего поля n. [11]

В Д this в методе класса, структуры или объединения относится к неизменяемой ссылке на экземпляр включающего агрегата. Классы являются ссылочными типами, а структуры и объединения — типами значений. В первой версии D ключевое слово this используется как указатель на экземпляр объекта, к которому привязан метод, тогда как в D2 он имеет характер неявного ref аргумент функции.

В языке программирования Dylan , который является объектно-ориентированным языком, поддерживающим мультиметоды и не имеющим понятия this, отправка сообщения объекту по-прежнему сохраняется в синтаксисе. Две формы ниже работают одинаково; различия — всего лишь синтаксический сахар .

object.method(param1, param2)

и

method (object, param1, param2)

Эйфелева

[ редактировать ]

В тексте класса текущий тип — это тип, полученный из текущего класса . Внутри функций (подпрограмм, команд и запросов) класса можно использовать ключевое слово Current для ссылки на текущий класс и его функции. Использование ключевого слова Current является необязательным в качестве ключевого слова Current подразумевается путем простого открытого обращения к имени текущего объекта класса. Например: в классе MY_CLASS может быть функция `foo', и обращаться к ней можно так:

  class
     MY_CLASS
  
  feature -- Access
  
     foo: INTEGER
  
     my_function: INTEGER
        do
          Result := foo
       end
 
 end

[12]

Строка № 10 (выше) содержит подразумеваемую ссылку на Current вызовом простой `foo'.

Строка № 10 (ниже) содержит явную ссылку на Current вызовом Current.foo.

  class
     MY_CLASS
  
  feature -- Access
  
     foo: INTEGER
  
     my_function: INTEGER
        do
           Result := Current.foo
       end
 
 end

Любой подход приемлем для компилятора, но подразумеваемая версия (например, x := foo) предпочтительнее, поскольку он менее многословен.

Как и в других языках, бывают случаи, когда использование ключевого слова Current является обязательным, например:

  class
     MY_CLASS
  
  feature -- Access
  
     my_command
           -- Create MY_OTHER_CLASS with `Current'
        local
           x: MY_OTHER_CLASS
       do
          create x.make_with_something (Current)
       end
 
 end

В случае приведенного выше кода вызов make_with_something в строке № 11 передает текущий класс путем явной передачи ключевого слова Current.

Ключевое слово this — это ключевое слово языка Java , которое представляет текущий экземпляр класса, в котором оно встречается. Он используется для доступа к переменным и методам класса.

Поскольку все методы экземпляра в Java виртуальны, this никогда не может быть нулевым. [13]

В JavaScript, который представляет собой язык программирования или сценариев, широко используемый в веб-браузерах, this — важное ключевое слово, хотя его значение зависит от того, где оно используется.

  • При использовании вне какой-либо функции в глобальном пространстве this ссылается на включающий объект, которым в данном случае является включающее окно браузера, window объект.
  • При использовании в функции, определенной в глобальном пространстве, какое ключевое слово this ссылается на зависит от того, как вызывается функция. Когда такая функция вызывается напрямую (например, f(x)), this будет ссылаться на глобальное пространство, в котором определена функция и в котором также могут существовать другие глобальные функции и переменные (или в строгом режиме, это undefined). Если глобальная функция, содержащая this вызывается как часть обработчика событий элемента объекта документа, однако this будет ссылаться на вызывающий элемент HTML.
  • Когда метод вызывается с использованием new ключевое слово (например var c = new Thing()) затем внутри Вещи this относится к самому объекту Thing.
  • Когда функция прикрепляется как свойство объекта и вызывается как метод этого объекта (например, obj.f(x)), this будет ссылаться на объект, внутри которого содержится функция. [14] [15] Можно даже вручную указать this при вызове функции с помощью .call() или .apply() методы объекта функции. [16] Например, вызов метода obj.f(x) также может быть записано как obj.f.call(obj, x).

Чтобы обойти различное значение this во вложенных функциях, таких как обработчики событий DOM, в JavaScript распространена идиома сохранения this ссылка на вызывающий объект в переменной (обычно называемой that или self), а затем используйте переменную для ссылки на вызывающий объект во вложенных функциях.

Например:

// In this example $ is a reference to the jQuery library 
$(".element").hover(function() {
    // Here, both this and that point to the element under the mouse cursor.
    var that = this;
    
    $(this).find('.elements').each(function() {
        // Here, this points to the DOM element being iterated.
        // However, that still points to the element under the mouse cursor.
        $(this).addClass("highlight");
    });
});

Примечательно, что JavaScript использует оба this и соответствующее ключевое слово self[17] (в отличие от большинства других языков, которые, как правило, используют тот или иной), с self ограничивается специально веб-работниками. [18]

Наконец, в качестве надежного способа конкретной ссылки на глобальный объект (окно или его эквивалент) в JavaScript реализована функция globalThis ключевое слово. [19]

В Луа, self создается как синтаксический сахар , когда функции определяются с использованием : оператор. [20] При вызове метода с использованием :, индексируемый объект будет неявно указан в качестве первого аргумента вызываемой функции.

Например, следующие две функции эквивалентны:

local obj = {}

function obj.foo(arg1, arg2)
  print(arg1, arg2) -- cannot use "self" here
end

function obj:bar(arg)
  print(self, arg) -- "self" is an implicit first argument before arg
end

-- All functions can be invoked both ways, with "." or with ":"

obj:foo("Foo") -- equivalent to obj.foo(obj, "Foo")
obj.bar(obj, "Bar") -- equivalent to obj:bar("Bar")

Lua сам по себе не является объектно-ориентированным, но в сочетании с другой функцией, называемой метатаблицами, использование self позволяет программистам определять функции способом, напоминающим объектно-ориентированное программирование.

В PowerShell специальная автоматическая переменная $_ содержит текущий объект в объекте конвейера. Эту переменную можно использовать в командах, которые выполняют действие над каждым объектом или над выбранными объектами в конвейере. [21]

"one", "two", "three" | % { write $_ }

Также начиная с PowerShell 5.0, в котором добавлен формальный синтаксис для определения классов и других определяемых пользователем типов. [22] $this Переменная описывает текущий экземпляр объекта.

В Python нет ключевого слова для this. Когда функция-член вызывается для объекта, она вызывает функцию-член с тем же именем в объекте класса объекта, при этом объект автоматически привязывается к первому аргументу функции. Таким образом, обязательным первым параметром методов экземпляра служит this; этот параметр условно назван self, но можно назвать как угодно.

В методах класса (созданных с помощью classmethod декоратор), первый аргумент относится к самому объекту класса и обычно называется cls; они в основном используются для наследуемых конструкторов, [23] где использование класса в качестве параметра позволяет создать подкласс конструктора. В статических методах (созданных с помощью staticmethod декоратор), специального первого аргумента не существует.

Ржавчина

[ редактировать ]

В Rust типы объявляются отдельно от связанных с ними функций. Функции, аналогичные методам экземпляров в более традиционных объектно-ориентированных языках, должны явно принимать self в качестве их первого параметра. Эти функции затем можно вызвать с помощью instance.method() синтаксический сахар. Например:

struct Foo {
    bar: i32,
}

impl Foo {
    fn new() -> Foo {
        Foo { bar: 0, }
    }
    fn refer(&self) {
        println!("{}", self.bar);
    }
    fn mutate(&mut self, baz: i32) {
        self.bar = baz;
    }
    fn consume(self) {
        self.refer();
    }
}

Это определяет тип, Foo, который имеет четыре связанные функции. Первый, Foo::new(), не является функцией экземпляра и должен быть указан с префиксом типа. Оставшиеся трое занимают self параметр различными способами и может быть вызван на Foo экземпляр с использованием синтаксиса точечной нотации, который эквивалентен вызову имени функции с указанием типа с явным self первый параметр.

let mut foo = Foo::new(); // must called as a type-specified function
foo.refer(); // prints "0". Foo::refer() has read-only access to the foo instance
foo.mutate(5); // mutates foo in place, permitted by the &mut specification, need foo to be declared mut
foo.consume(); // prints "5" and destroys foo, as Foo::consume() takes full ownership of self

//  equivalent to foo.refer()
Foo::refer(foo); // compilation error: foo is out of scope

Язык Self назван в честь этого использования слова «self».

Self используется строго внутри методов класса. Еще один способ обратиться к Self это использовать ::.

См. также

[ редактировать ]
  1. ^ Даль, Оле-Йохан ; Мирхауг, Бьёрн; Найгаард, Кристен (1970). «Общий базовый язык, Норвежский вычислительный центр» .
  2. ^ Пауэлл, Томас А., и Шнайдер, Фриц, 2012. JavaScript: Полный справочник, третье издание. МакГроу-Хилл. Глава 11, Обработка событий , стр. 428. ISBN   978-0-07-174120-0
  3. ^ Использование коллекции компиляторов GNU (GCC) — привязанные функции-члены.
  4. ^ « Закрытая и открытая рекурсия », Ральф Хинце , июль 2007 г.
  5. ^ Открытая рекурсия , Lambda the Ultimate
  6. ^ « Выборочная открытая рекурсия: решение проблемы хрупкого базового класса », Джонатан Олдрич
  7. ^ « Выборочная открытая рекурсия: решение проблемы хрупкого базового класса », Lambda the Ultimate
  8. ^ Олдрич, Джонатан и Кевин Доннелли. « Выборочная открытая рекурсия: модульные рассуждения о компонентах и ​​наследовании ». SAVCBS 2004 Спецификация и проверка компонентно-ориентированных систем (2004): 26. со ссылкой на решение, принятое в JDK, C. Ruby и GT Leavens. «Безопасное создание правильных подклассов, не видя кода суперкласса». В «Системах объектно-ориентированного программирования, языках и приложениях», октябрь 2000 г. doi : 10.1145/353171.353186 также доступен в виде технического отчета TR № 00-05d.
  9. ^ ISO/IEC 14882:2003(E): Языки программирования — C++ . ИСО/МЭК. 2003.
  10. ^ Страуструп: Часто задаваемые вопросы по стилю и технике C++
  11. ^ Де Смет, Барт, 2011. C# 4.0 выпущен на свободу. Издательство Sams, Индианаполис, США. Глава 4, Основы языка , стр. 210. ISBN   978-0-672-33079-7
  12. ^ ПРИМЕЧАНИЕ. Номера строк предназначены только для справочных целей. У Eiffel нет номеров строк в тексте класса. Однако в Eiffel Studio IDE есть опция номера строки, которую можно дополнительно включить для справочных целей (например, парное программирование и т. д.).
  13. ^ Барнс, Д. и Кёллинг, М. Сначала объекты с Java . «...причина использования этой конструкции [this] заключается в том, что мы имеем ситуацию, известную как перегрузка имени : одно и то же имя используется для двух разных объектов... Важно понимать, что поля и параметры отдельные переменные, которые существуют независимо друг от друга, даже если они имеют одинаковые имена. Параметр и поле, имеющие одно и то же имя, не являются проблемой в Java». [ нужна ссылка ]
  14. ^ Крокфорд, Дуглас, 2008. JavaScript: хорошие стороны . O'Reilly Media Inc. и Yahoo! Inc. Глава 4, Функции , стр. 28. ISBN   978-0-596-51774-8
  15. ^ Пауэлл, Томас А., и Шнайдер, Фриц, 2012. JavaScript: Полный справочник, третье издание. МакГроу-Хилл. Глава 5, Функции , стр. 170–1. ISBN   978-0-07-174120-0
  16. ^ Гудман, Дэнни, с Моррисоном, Майклом, 2004. Библия JavaScript, 5-е издание. Wiley Publishing, Inc., Индианаполис, США. Глава 33, Функции и пользовательские объекты , стр. 987. ISBN   0-7645-5743-2
  17. ^ Сеть разработчиков Mozilla : Window.self
  18. ^ Сеть разработчиков Mozilla : API веб-работников
  19. ^ Сеть разработчиков Mozilla : globalThis
  20. ^ «Программирование на Lua: 16» .
  21. ^ MSDN. «PowerShell: об автоматических переменных» . docs.microsoft.com . Проверено 22 марта 2018 г.
  22. ^ MSDN. "о_классах" . docs.microsoft.com . Проверено 17 декабря 2018 г.
  23. ^ Объединение типов и классов в Python 2.2, Гвидо ван Россум, « Переопределение метода __new__ »

Дальнейшее чтение

[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 8e9f52fafe60ea4b8de05f0159499555__1709993880
URL1:https://arc.ask3.ru/arc/aa/8e/55/8e9f52fafe60ea4b8de05f0159499555.html
Заголовок, (Title) документа по адресу, URL1:
this (computer programming) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)