to (programowanie komputerowe) - this (computer programming)

this , self i Mesłowami kluczowymi używanymi w niektórych językach programowania komputerowego w odniesieniu do obiektu, klasy lub innej jednostki, której częścią jest aktualnie uruchomiony kod. Jednostka, do której odwołują się te słowa kluczowe, zależy zatem od kontekstu wykonania (np. który obiekt ma wywołaną metodę). Różne języki programowania używają tych słów kluczowych w nieco inny sposób. W językach, w których słowo kluczowe takie jak „this” jest obowiązkowe, słowo kluczowe jest jedynym sposobem uzyskania dostępu do danych i metod przechowywanych w bieżącym obiekcie. Tam, gdzie jest to opcjonalne, mogą rozróżniać zmienne i funkcje o tej samej nazwie.

Programowanie obiektowe

W wielu obiektowych językach programowania , this(nazywany również selflub Me) jest zmienną, która jest używana w metodach instancji do odwoływania się do obiektu, na którym pracują. Pierwszy język obiektowy, SIMULA 67 , używany thisdo jawnego odwoływania się do obiektu lokalnego. C++ i języki, które wywodzą się z niego w stylu (takie jak Java , C# , D i PHP ) również ogólnie używają this. Smalltalk i inne, takie jak Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex i Swift , używają self. Visual Basic firmy Microsoft wykorzystuje Me.

Pojęcie jest podobne we wszystkich językach: thisjest zwykle niezmiennym odniesieniem lub wskaźnikiem, który odnosi się do bieżącego obiektu; bieżący obiekt często jest kodem, który działa jako „rodzic” dla właściwości , metody , podprogramu lub funkcji zawierającej thissłowo kluczowe. Po prawidłowym skonstruowaniu lub utworzeniu instancji obiektu thiszawsze jest poprawnym odniesieniem. Niektóre języki wymagają tego wprost; inni używają zakresu leksykalnego, aby użyć go w sposób niejawny, aby symbole w ich klasie były widoczne. Alternatywnie, bieżący obiekt, do którego odwołuje się thismoże być niezależnym obiektem kodu, który wywołał funkcję lub metodę zawierającą słowo kluczowe this. Taka rzecz ma miejsce, na przykład, gdy moduł obsługi zdarzeń JavaScript dołączony do znacznika HTML na stronie internetowej wywołuje funkcję zawierającą słowo kluczowe thisprzechowywane w globalnej przestrzeni poza obiektem dokumentu; w tym kontekście thisbędzie odnosić się do elementu strony w obiekcie dokumentu, a nie do otaczającego obiektu okna.

W niektórych językach, na przykład C++ i Java, thislub selfjest słowem kluczowym , a zmienna automatycznie istnieje w metodach instancji. W innych, na przykład Python, Rust i Perl 5, pierwszym parametrem metody instancji jest taka referencja. Musi być wyraźnie określony. W Pythonie i Perlu parametr nie musi być koniecznie nazwany thislub self; może być dowolnie nazwany przez programistę, jak każdy inny parametr. Jednak zgodnie z nieformalną konwencją pierwszy parametr metody instancji w Perlu lub Pythonie ma nazwę self. Rust wymaga wywołania obiektu self &selflub self, w zależności od tego, czy wywoływana funkcja odpowiednio pożycza inwokator, czy przenosi go.

Metody statyczne w C++ lub Javie nie są powiązane z instancjami, ale z klasami, a więc nie mogą używać this, ponieważ nie ma obiektu. W innych językach, takich jak Ruby, Smalltalk, Objective-C lub Swift, metoda jest powiązana z obiektem klasy, który jest przekazywany jako this, i są one nazywane metodami klas . W przypadku metod klasowych Python używa clsdostępu do obiektu klasy .

Subtelności i trudności

Kiedy zakres leksykalny jest używany do wnioskowania this, użycie thisin w kodzie, chociaż nie jest nielegalne, może wywołać ostrzeżenie dla programisty zajmującego się konserwacją, chociaż nadal istnieją legalne zastosowania thisw tym przypadku, takie jak odwoływanie się do zmiennych instancji ukrytych przez lokalne zmienne o tej samej nazwie, lub jeśli metoda chce zwrócić referencję do bieżącego obiektu, tj this. do samej siebie.

W niektórych kompilatorach (na przykład GCC ) wskaźniki do metod instancji C++ mogą być bezpośrednio rzutowane na wskaźnik innego typu z jawnym thisparametrem wskaźnika.

Otwarta rekursja

Semantyka wysyłania this, a mianowicie to, że wywołania metod thissą wysyłane dynamicznie, jest znana jako otwarta rekursja i oznacza, że ​​te metody mogą być zastępowane przez klasy pochodne lub obiekty. Natomiast bezpośrednia nazwana rekursja lub anonimowa rekurencja funkcji używa zamkniętej rekurencji z wczesnym wiązaniem. Na przykład w poniższym kodzie Perla dla silni, token __SUB__jest odwołaniem do bieżącej funkcji:

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

W przeciwieństwie do tego, w C++ (używając wyraźnego thisdla jasności, choć nie jest to konieczne) thiswiąże się z samym obiektem, ale jeśli metoda klasy została zadeklarowana jako „wirtualna”, tj. polimorficzna w bazie, jest rozwiązywana przez dynamiczną wysyłkę ( późne wiązanie ), aby klasy pochodne mogą to zastąpić.

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

Ten przykład jest sztuczny, ponieważ jest to rekurencja bezpośrednia, więc factorialprzesłonięcie metody spowoduje przesłonięcie tej funkcji; bardziej naturalne przykłady są wtedy, gdy metoda w klasie pochodnej wywołuje tę samą metodę w klasie bazowej lub w przypadkach wzajemnej rekurencji.

Problem kruchej klasy bazowej został obwiniony na otwartą rekurencję, z sugestią, że wywoływanie metod thisdomyślnie na rekurencję zamkniętą (dystrybucja statyczna, wczesne wiązanie) zamiast otwartej rekurencji (dystrybucja dynamiczna, późne wiązanie), przy użyciu otwartej rekurencji, gdy jest to konkretnie wymagany; wywołania zewnętrzne (nie używające this) byłyby jak zwykle wysyłane dynamicznie. Sposób, w jaki jest to rozwiązywane w praktyce w JDK, polega na pewnej dyscyplinie programistycznej; dyscyplina ta została sformalizowana przez C. Ruby i GT Leavens; zasadniczo składa się z następujących zasad:

  • Żaden kod nie wywołuje publicmetod na this.
  • Kod, który może być ponownie użyty wewnętrznie (poprzez wywołanie z innych metod tej samej klasy) jest zawarty w metodzie protectedlub private; jeśli musi być również udostępniony bezpośrednio użytkownikom, publicmetoda opakowująca wywołuje metodę wewnętrzną.
  • Poprzednie zalecenie można złagodzić w przypadku czystych metod.

Realizacje

C++

Wczesne wersje C++ pozwalały na zmianę thiswskaźnika; w ten sposób programista może zmienić obiekt, nad którym pracuje metoda. Ta funkcja została ostatecznie usunięta, a teraz thisw C++ jest r-value .

Wczesne wersje C++ nie zawierały referencji i sugerowano, że gdyby były tak w C++ od samego początku, thisbyłyby referencją, a nie wskaźnikiem.

C++ pozwala obiektom niszczyć się same za pomocą instrukcji kodu źródłowego: delete this.

C#

Słowo kluczowe thisw C# działa tak samo jak w Javie, dla typów referencyjnych. Jednak w C # typów wartości , thisma zupełnie różne semantyki, jest podobny do zwykłego zmienny odniesienia zmiennej, a nawet może pojawić się po lewej stronie przypisania.

Jednym z zastosowań thisw C# jest umożliwienie odwołania do zmiennej pola zewnętrznego w metodzie, która zawiera zmienną lokalną o tej samej nazwie. W takiej sytuacji np. instrukcja var n = localAndFieldname;w metodzie przypisze typ i wartość zmiennej lokalnej localAndFieldnamedo n, natomiast instrukcja var n = this.localAndFieldname;przypisze typ i wartość zmiennej pola zewnętrznego do n.

D

W D this w klasie metoda struct lub union odwołuje się do niezmiennego odwołania do wystąpienia otaczającej agregacji. Klasy są typami referencyjnymi , struktury i związki są typami wartości. W pierwszej wersji D słowo kluczowe thisjest używane jako wskaźnik do instancji obiektu, z którym jest powiązana metoda, podczas gdy w D2 ma charakter niejawnego refargumentu funkcji.

Dylan

W języku programowania Dylan , który jest językiem zorientowanym obiektowo, który obsługuje wiele metod i nie ma koncepcji this, wysyłanie wiadomości do obiektu jest nadal utrzymywane w składni. Dwie poniższe formy działają w ten sam sposób; różnice to tylko cukier składniowy .

object.method(param1, param2)

oraz

method (object, param1, param2)

Eiffla

W tekście klasy bieżący typ jest typem uzyskanym z bieżącej klasy . W obrębie cech (programów, poleceń i zapytań) klasy można użyć słowa kluczowego Currentdo odniesienia się do bieżącej klasy i jej cech. Użycie słowa kluczowego Currentjest opcjonalne, ponieważ słowo kluczowe Currentwynika po prostu z otwartego odwoływania się do nazwy bieżącej funkcji klasy. Na przykład: Można mieć funkcję `foo' w klasie MY_CLASS i odwoływać się do niej przez:

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

Wiersz #10 (powyżej) zawiera dorozumiane odwołanie Currentdo prostego `foo'.

Wiersz #10 (poniżej) zawiera wyraźne odniesienie do Currentwywołania `Current.foo'.

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

Każde z tych podejść jest akceptowalne przez kompilator, ale x := foopreferowana jest wersja dorozumiana (np. ), ponieważ jest mniej gadatliwa.

Podobnie jak w przypadku innych języków, zdarza się, że użycie słowa kluczowego Currentjest obowiązkowe, na przykład:

  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

W przypadku powyższego kodu, wywołanie w linii nr 11 funkcji make_with_something przekazuje bieżącą klasę przez jawne przekazanie słowa kluczowego Current.

Jawa

Słowo kluczowe thisto słowo kluczowe języka Java , które reprezentuje bieżącą instancję klasy, w której się pojawia. Służy do uzyskiwania dostępu do zmiennych i metod klas.

Ponieważ wszystkie metody instancji są wirtualne w Javie, thisnigdy nie mogą być puste.

JavaScript

W JavaScript, który jest językiem programowania lub skryptowym używanym szeroko w przeglądarkach internetowych, thisjest ważnym słowem kluczowym, chociaż jego wartość zależy od tego, gdzie jest używane.

  • Używane poza jakąkolwiek funkcją, w przestrzeni globalnej, thisodnosi się do otaczającego obiektu, którym w tym przypadku jest otaczające okno przeglądarki, windowobiekt.
  • W przypadku użycia w funkcji zdefiniowanej w przestrzeni globalnej to, do czego thisodnosi się słowo kluczowe, zależy od sposobu wywołania funkcji. Gdy taka funkcja zostanie wywołana bezpośrednio (np. f(x)), thisodniesie się z powrotem do przestrzeni globalnej, w której funkcja jest zdefiniowana iw której mogą istnieć również inne globalne funkcje i zmienne (lub w trybie ścisłym jest to undefined). Jeśli jednak funkcja globalna zawierająca thisjest wywoływana jako część procedury obsługi zdarzenia elementu w obiekcie dokumentu, thisbędzie odnosić się do wywołującego elementu HTML.
  • Gdy metoda jest wywoływana przy użyciu newsłowa kluczowego (np. var c = new Thing()), to wewnątrz Thing thisodwołuje się do samego obiektu Thing.
  • Gdy funkcja jest dołączona jako właściwość obiektu i wywołana jako metoda tego obiektu (np. obj.f(x)), thisbędzie odnosić się do obiektu, w którym funkcja jest zawarta. Możliwe jest nawet ręczne określenie thispodczas wywoływania funkcji za pomocą metod .call()lub .apply()obiektu funkcji. Na przykład wywołanie metody obj.f(x)może być również zapisane jako obj.f.call(obj, x).

Aby obejść różne znaczenie thisfunkcji zagnieżdżonych, takich jak moduły obsługi zdarzeń DOM, powszechnym idiomem w JavaScript jest zapisanie thisodwołania do obiektu wywołującego w zmiennej (powszechnie wywoływanej thatlub self), a następnie użycie zmiennej do odwołania się do wywołującego obiekt w zagnieżdżonych funkcjach.

Na przykład:

// 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");
    });
});

Warto zauważyć, że JavaScript korzysta z obu thisi powiązanych słów kluczowych self(w przeciwieństwie do większości innych języków, które mają tendencję do używania jednego lub drugiego), z selfograniczeniem do pracowników sieci.

Wreszcie, jako niezawodny sposób odwoływania się do obiektu globalnego (okna lub odpowiednika), JavaScript zawiera globalThissłowo kluczowe.

Lua

W Lua selfjest tworzony jako cukier składniowy, gdy funkcje są definiowane za pomocą :operatora. Podczas wywoływania metody przy użyciu :indeksowany obiekt zostanie niejawnie podany jako pierwszy argument wywoływanej funkcji.

Na przykład następujące dwie funkcje są równoważne:

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")

Sam Lua nie jest zorientowany obiektowo, ale w połączeniu z inną funkcją zwaną metatablicami, użycie selfpozwala programistom definiować funkcje w sposób przypominający programowanie obiektowe.

PowerShell

W PowerShell specjalna zmienna automatyczna $_ zawiera bieżący obiekt w obiekcie potoku. Tej zmiennej można używać w poleceniach, które wykonują akcję na każdym obiekcie lub na wybranych obiektach w potoku.

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

Również począwszy od PowerShell 5.0, który dodaje formalną składnię do definiowania klas i innych typów zdefiniowanych przez użytkownika, $thiszmienna opisuje bieżące wystąpienie obiektu.

Pyton

W Pythonie nie ma słowa kluczowego dla this. Gdy funkcja składowa jest wywoływana na obiekcie, wywołuje funkcję składową o tej samej nazwie w obiekcie klasy obiektu, z obiektem automatycznie powiązanym z pierwszym argumentem funkcji. Zatem obowiązkowy pierwszy parametr metod instancji służy jako this; ten parametr jest konwencjonalnie nazywany self, ale można go nazwać dowolną.

W metodach klasowych (tworzonych za pomocą classmethoddekoratora) pierwszy argument odnosi się do samego obiektu klasy i jest konwencjonalnie nazywany cls; są one używane głównie w przypadku konstruktorów dziedzicznych, w których użycie klasy jako parametru umożliwia tworzenie podklas konstruktora. W metodach statycznych (tworzonych za pomocą staticmethoddekoratora) nie istnieje żaden specjalny pierwszy argument.

Rdza

W Ruście typy są deklarowane oddzielnie od funkcji z nimi związanych. Funkcje zaprojektowane jako analogiczne do metod instancji w bardziej tradycyjnych językach obiektowych muszą jawnie przyjmować selfjako pierwszy parametr. Funkcje te można następnie wywołać za pomocą instance.method()cukru składniowego. Na przykład:

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();
    }
}

Definiuje typ Foo, który ma cztery powiązane funkcje. Pierwsza, Foo::new(), nie jest funkcją wystąpienia i musi być określona z prefiksem typu. Wszystkie pozostałe trzy przyjmują selfparametr na różne sposoby i można je wywołać w Fooinstancji przy użyciu cukru składni z kropkami, co jest równoważne wywołaniu nazwy funkcji kwalifikowanej typu z jawnym selfpierwszym parametrem.

let 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
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

Samego siebie

Język Self został nazwany po tym użyciu „ja”.

Xbase++

Selfjest ściśle używany w ramach metod klasy. Innym sposobem odwoływania się Selfjest użycie ::.

Zobacz też

Bibliografia

Dalsza lektura