to (programowanie komputerowe) - this (computer programming)
this , self i Me są sł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ż self
lub 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 this
do 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: this
jest 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 this
słowo kluczowe. Po prawidłowym skonstruowaniu lub utworzeniu instancji obiektu this
zawsze 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ę this
moż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 this
przechowywane w globalnej przestrzeni poza obiektem dokumentu; w tym kontekście this
bę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, this
lub self
jest 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 this
lub 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 &self
lub 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 cls
dostępu do obiektu klasy .
Subtelności i trudności
Kiedy zakres leksykalny jest używany do wnioskowania this
, użycie this
in w kodzie, chociaż nie jest nielegalne, może wywołać ostrzeżenie dla programisty zajmującego się konserwacją, chociaż nadal istnieją legalne zastosowania this
w 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 this
parametrem wskaźnika.
Otwarta rekursja
Semantyka wysyłania this
, a mianowicie to, że wywołania metod this
są 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 this
dla jasności, choć nie jest to konieczne) this
wiąż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 factorial
przesł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 this
domyś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
public
metod nathis
. - Kod, który może być ponownie użyty wewnętrznie (poprzez wywołanie z innych metod tej samej klasy) jest zawarty w metodzie
protected
lubprivate
; jeśli musi być również udostępniony bezpośrednio użytkownikom,public
metoda 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ę this
wskaźnika; w ten sposób programista może zmienić obiekt, nad którym pracuje metoda. Ta funkcja została ostatecznie usunięta, a teraz this
w C++ jest r-value .
Wczesne wersje C++ nie zawierały referencji i sugerowano, że gdyby były tak w C++ od samego początku, this
był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 this
w C# działa tak samo jak w Javie, dla typów referencyjnych. Jednak w C # typów wartości , this
ma 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ń this
w 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 localAndFieldname
do 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 this
jest używane jako wskaźnik do instancji obiektu, z którym jest powiązana metoda, podczas gdy w D2 ma charakter niejawnego ref
argumentu 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 Current
do odniesienia się do bieżącej klasy i jej cech. Użycie słowa kluczowego Current
jest opcjonalne, ponieważ słowo kluczowe Current
wynika 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 Current
do prostego `foo'.
Wiersz #10 (poniżej) zawiera wyraźne odniesienie do Current
wywoł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 := foo
preferowana jest wersja dorozumiana (np. ), ponieważ jest mniej gadatliwa.
Podobnie jak w przypadku innych języków, zdarza się, że użycie słowa kluczowego Current
jest 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 this
to 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, this
nigdy nie mogą być puste.
JavaScript
W JavaScript, który jest językiem programowania lub skryptowym używanym szeroko w przeglądarkach internetowych, this
jest 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,
this
odnosi się do otaczającego obiektu, którym w tym przypadku jest otaczające okno przeglądarki,window
obiekt. - W przypadku użycia w funkcji zdefiniowanej w przestrzeni globalnej to, do czego
this
odnosi się słowo kluczowe, zależy od sposobu wywołania funkcji. Gdy taka funkcja zostanie wywołana bezpośrednio (np.f(x)
),this
odniesie 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 toundefined
). Jeśli jednak funkcja globalna zawierającathis
jest wywoływana jako część procedury obsługi zdarzenia elementu w obiekcie dokumentu,this
będzie odnosić się do wywołującego elementu HTML. - Gdy metoda jest wywoływana przy użyciu
new
słowa kluczowego (np.var c = new Thing()
), to wewnątrz Thingthis
odwoł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)
),this
będzie odnosić się do obiektu, w którym funkcja jest zawarta. Możliwe jest nawet ręczne określeniethis
podczas wywoływania funkcji za pomocą metod.call()
lub.apply()
obiektu funkcji. Na przykład wywołanie metodyobj.f(x)
może być również zapisane jakoobj.f.call(obj, x)
.
Aby obejść różne znaczenie this
funkcji zagnieżdżonych, takich jak moduły obsługi zdarzeń DOM, powszechnym idiomem w JavaScript jest zapisanie this
odwołania do obiektu wywołującego w zmiennej (powszechnie wywoływanej that
lub 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 this
i 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 self
ograniczeniem do pracowników sieci.
Wreszcie, jako niezawodny sposób odwoływania się do obiektu globalnego (okna lub odpowiednika), JavaScript zawiera globalThis
słowo kluczowe.
Lua
W Lua self
jest 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 self
pozwala 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, $this
zmienna 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ą classmethod
dekoratora) 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ą staticmethod
dekoratora) 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ć self
jako 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ą self
parametr na różne sposoby i można je wywołać w Foo
instancji przy użyciu cukru składni z kropkami, co jest równoważne wywołaniu nazwy funkcji kwalifikowanej typu z jawnym self
pierwszym 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++
Self
jest ściśle używany w ramach metod klasy. Innym sposobem odwoływania się Self
jest użycie ::
.
Zobacz też
- Rekurencja anonimowa – Rekurencja bez wywoływania funkcji według nazwy
- Dziedziczenie (programowanie obiektowe) – Mechanizm opierania obiektu lub klasy na innym obiekcie lub klasie zachowującej podobną implementację
- Odniesienie do siebie – zdanie, idea lub formuła, która odnosi się do siebie
- Schizofrenia (programowanie obiektowe) – Komplikacja wynikająca z delegowania i powiązanych technik w programowaniu obiektowym
- Prefiks segmentu programu – struktura danych w DOS
Bibliografia
Dalsza lektura
- Meyers, Scott, 1995. Wydajniejszy C++: 35 nowych sposobów ulepszania programów i projektów . ISBN 0-201-63371-X Scott Meyers
- Stroustrup, Bjarne, 1994. Projekt i ewolucja C++ . Pub Addison-Wesley. Co. ISBN 0-201-54330-3 Bjarne Stroustrup