isto (programação de computador) - this (computer programming)

this , self e Me são palavras-chave usadas em algumas linguagens de programação de computador para se referir ao objeto, classe ou outra entidade da qual o código atualmente em execução faz parte. A entidade referida por essas palavras-chave depende, portanto, do contexto de execução (por exemplo, qual objeto está tendo seu método chamado). Diferentes linguagens de programação usam essas palavras-chave de maneiras ligeiramente diferentes. Em idiomas onde uma palavra-chave como "this" é obrigatória, a palavra-chave é a única forma de acessar dados e métodos armazenados no objeto atual. Onde for opcional, eles podem eliminar a ambiguidade de variáveis ​​e funções com o mesmo nome.

Programação orientada a objetos

Em muitas linguagens de programação orientadas a objetos , this(também chamado de selfou Me) é uma variável que é usada em métodos de instância para se referir ao objeto no qual estão trabalhando. A primeira linguagem OO, SIMULA 67 , usada thispara referenciar explicitamente o objeto local. C ++ e linguagens que derivam em estilo dele (como Java , C # , D e PHP ) também costumam usar this. Smalltalk e outros, como Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex e Swift , usam self. O Visual Basic da Microsoft usa Me.

O conceito é semelhante em todas as linguagens: thisgeralmente é uma referência ou ponteiro imutável que se refere ao objeto atual; o objeto atual geralmente é o código que atua como 'pai' para a propriedade , método , sub-rotina ou função que contém a thispalavra - chave. Depois que um objeto é construído corretamente, ou instanciado, thisé sempre uma referência válida. Algumas linguagens exigem isso explicitamente; outros usam escopo léxico para usá-lo implicitamente para tornar os símbolos dentro de sua classe visíveis. Ou, alternativamente, o objeto atual referido por thispode ser um objeto de código independente que chamou a função ou método que contém a palavra-chave this. Isso acontece, por exemplo, quando um manipulador de eventos JavaScript anexado a uma tag HTML em uma página da web chama uma função contendo a palavra-chave thisarmazenada no espaço global fora do objeto de documento; nesse contexto, thisfará referência ao elemento da página dentro do objeto do documento, não ao objeto da janela envolvente.

Em algumas linguagens, por exemplo C ++ e Java, thisou selfé uma palavra - chave , e a variável existe automaticamente nos métodos de instância. Em outros, por exemplo Python, Rust e Perl 5, o primeiro parâmetro de um método de instância é essa referência. Precisa ser especificado explicitamente. Em Python e Perl, o parâmetro não precisa necessariamente ser nomeado thisou self; ele pode ser nomeado livremente pelo programador como qualquer outro parâmetro. No entanto, por convenção informal, o primeiro parâmetro de um método de instância em Perl ou Python é nomeado self. Rust requer que o objeto self seja chamado &selfou self, dependendo se a função chamada toma emprestado o invocante ou o move, respectivamente.

Os métodos estáticos em C ++ ou Java não estão associados a instâncias, mas classes e, portanto, não podem ser usados this, porque não há objeto. Em outras linguagens, como Ruby, Smalltalk, Objective-C ou Swift, o método é associado a um objeto de classe que é passado como thise são chamados de métodos de classe . Para métodos de classe, Python usa clspara acessar o objeto de classe .

Sutilezas e dificuldades

Quando o escopo léxico é usado para inferir this, o uso de thisno código, embora não seja ilegal, pode levantar avisos para um programador de manutenção, embora ainda haja usos legítimos de thisneste caso, como referir-se a variáveis ​​de instância ocultas por variáveis ​​locais do mesmo nome, ou se o método quiser retornar uma referência ao objeto atual, ou seja this, ele mesmo.

Em alguns compiladores (por exemplo, GCC ), ponteiros para métodos de instância C ++ podem ser convertidos diretamente para um ponteiro de outro tipo, com um thisparâmetro de ponteiro explícito .

Recursão aberta

A semântica de despacho de this, ou seja, que as chamadas de método thissão despachadas dinamicamente, é conhecida como recursão aberta e significa que esses métodos podem ser substituídos por classes ou objetos derivados. Por outro lado, recursão nomeada direta ou recursão anônima de uma função usa recursão fechada , com vinculação inicial. Por exemplo, no seguinte código Perl para o fatorial, o token __SUB__é uma referência à função atual:

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

Por outro lado, em C ++ (usando um explícito thispara maior clareza, embora não seja necessário) o thisvincula ao próprio objeto, mas se o método de classe foi declarado "virtual", ou seja, polimórfico na base, é resolvido por meio de despacho dinâmico ( vinculação tardia ) para que classes derivadas podem substituí-lo.

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

Este exemplo é artificial, uma vez que se trata de recursão direta, portanto, sobrescrever o factorialmétodo sobrescreveria essa função; exemplos mais naturais são quando um método em uma classe derivada chama o mesmo método em uma classe base ou em casos de recursão mútua.

O frágil problema da classe base foi responsabilizado pela recursão aberta, com a sugestão de invocar métodos thispadrão para recursão fechada (despacho estático, vinculação antecipada) em vez de recursão aberta (despacho dinâmico, vinculação tardia), apenas usando recursão aberta quando é especificamente Requeridos; chamadas externas (não usando this) seriam despachadas dinamicamente como de costume. A maneira como isso é resolvido na prática no JDK é por meio de uma certa disciplina do programador; esta disciplina foi formalizada por C. Ruby e GT Leavens; basicamente consiste nas seguintes regras:

  • Nenhum código invoca publicmétodos em this.
  • O código que pode ser reutilizado internamente (por invocação de outros métodos da mesma classe) é encapsulado em um método protectedou private; se também precisar ser exposto diretamente aos usuários, um publicmétodo wrapper chama o método interno.
  • A recomendação anterior pode ser relaxada para métodos puros .

Implementações

C ++

As versões anteriores do C ++ permitiam que o thisponteiro fosse alterado; ao fazer isso, um programador poderia alterar em qual objeto um método estava trabalhando. Esse recurso foi eventualmente removido e agora thisem C ++ é um valor r .

As primeiras versões de C ++ não incluíam referências e foi sugerido que se tivessem sido em C ++ desde o início, thisteriam sido uma referência, não um ponteiro.

C ++ permite que objetos se destroem com a afirmação de código fonte: delete this.

C #

A palavra-chave thisem C # funciona da mesma maneira que em Java, para tipos de referência. No entanto, dentro dos tipos de valor C # , thistem uma semântica bastante diferente, sendo semelhante a uma referência de variável mutável comum, e pode até ocorrer no lado esquerdo de uma atribuição.

Um uso de thisem C # é permitir a referência a uma variável de campo externa dentro de um método que contém uma variável local com o mesmo nome. Em tal situação, por exemplo, a instrução var n = localAndFieldname;dentro do método atribuirá o tipo e o valor da variável local localAndFieldnamea n, enquanto a instrução var n = this.localAndFieldname;atribuirá o tipo e o valor da variável de campo externa a n.

D

Em D this em uma classe, struct ou método de união se refere a uma referência imutável da instância do agregado envolvente. Classes são tipos de referência , structs e uniões são tipos de valor. Na primeira versão de D, a palavra this- chave é usada como um ponteiro para a instância do objeto ao qual o método está vinculado, enquanto em D2 ela tem o caráter de um refargumento de função implícito .

Dylan

Na linguagem de programação Dylan , que é uma linguagem orientada a objetos que suporta multimétodos e não tem o conceito de this, o envio de uma mensagem para um objeto ainda é mantido na sintaxe. Os dois formulários abaixo funcionam da mesma maneira; as diferenças são apenas açúcar sintático .

object.method(param1, param2)

e

method (object, param1, param2)

Eiffel

Dentro de um texto de classe, o tipo atual é o tipo obtido da classe atual . Dentro dos recursos (rotinas, comandos e consultas) de uma classe, pode-se usar a palavra Current- chave para fazer referência à classe atual e seus recursos. O uso da palavra Current- chave é opcional, pois a palavra Current- chave está implícita na simples referência ao nome do recurso de classe atual abertamente. Por exemplo: Alguém pode ter um recurso `foo 'em uma classe MY_CLASS e se referir a ele por:

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

A linha # 10 (acima) tem a referência implícita Currentpela chamada a `foo 'simples.

A linha # 10 (abaixo) tem a referência explícita Currentpela chamada a `Current.foo '.

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

Qualquer uma das abordagens é aceitável para o compilador, mas a versão implícita (por exemplo x := foo) é preferida, pois é menos prolixa.

Assim como em outros idiomas, há momentos em que o uso da palavra Current- chave é obrigatório, como:

  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

No caso do código acima, a chamada na linha # 11 para make_with_something está passando a classe atual passando explicitamente a palavra-chave Current.

Java

A palavra this- chave é uma palavra-chave da linguagem Java que representa a instância atual da classe em que aparece. É usado para acessar variáveis ​​e métodos de classe.

Como todos os métodos de instância são virtuais em Java, thisnunca pode ser nulo.

JavaScript

Em JavaScript, que é uma linguagem de programação ou script usada extensivamente em navegadores da web, thisé uma palavra-chave importante, embora sua avaliação dependa de onde é usada.

  • Quando usado fora de qualquer função, no espaço global, thisrefere-se ao objeto envolvente, que neste caso é a janela do navegador envolvente, o windowobjeto.
  • Quando usado em uma função definida no espaço global, o que a palavra-chave thisse refere depende de como a função é chamada. Quando tal função é chamada diretamente (por exemplo f(x)), thisfará referência ao espaço global no qual a função está definida, e no qual outras funções e variáveis ​​globais também podem existir (ou no modo estrito, ele é undefined). Se uma função global contendo thisfor chamada como parte do manipulador de eventos de um elemento no objeto de documento, no entanto, thisfará referência ao elemento HTML de chamada.
  • Quando um método é chamado usando a newpalavra - chave (por exemplo var c = new Thing()), em Thing thisse refere ao próprio objeto Thing.
  • Quando uma função é anexada como uma propriedade de um objeto e chamada como um método desse objeto (por exemplo obj.f(x)), thisfará referência ao objeto no qual a função está contida. É ainda possível especificar manualmente thisao chamar uma função, usando os métodos .call()ou .apply()do objeto de função. Por exemplo, a chamada do método obj.f(x)também pode ser escrita como obj.f.call(obj, x).

Para contornar o significado diferente de thisfunções aninhadas, como manipuladores de eventos DOM, é um idioma comum em JavaScript salvar a thisreferência do objeto de chamada em uma variável (comumente chamada de thatou self) e, em seguida, usar a variável para se referir à chamada objeto em funções aninhadas.

Por exemplo:

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

Notavelmente, JavaScript faz uso de ambos thise da palavra-chave relacionada self(em contraste com a maioria das outras linguagens que tendem a empregar um ou outro), selfsendo restrito especificamente a web workers.

Finalmente, como uma forma confiável de referenciar especificamente o objeto global (janela ou equivalente), o JavaScript apresenta a globalThispalavra - chave.

Lua

Em Lua, selfé criado como açúcar sintático quando funções são definidas usando o :operador. Ao invocar um método usando :, o objeto que está sendo indexado será fornecido implicitamente como o primeiro argumento para a função que está sendo invocada.

Por exemplo, as duas funções a seguir são equivalentes:

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 em si não é orientada a objetos, mas quando combinada com outro recurso chamado meta-tabelas, o uso de selfpermite que os programadores definam funções de maneira semelhante à programação orientada a objetos.

PowerShell

No PowerShell, a variável automática especial $_contém o objeto atual no objeto de pipeline. Você pode usar essa variável em comandos que executam uma ação em cada objeto ou em objetos selecionados em um pipeline.

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

Também começando com o PowerShell 5.0, que adiciona uma sintaxe formal para definir classes e outros tipos definidos pelo usuário, a $thisvariável descreve a instância atual do objeto.

Pitão

Em Python, não há palavra-chave para this. Quando uma função de membro é chamada em um objeto, ela chama a função de membro com o mesmo nome no objeto de classe do objeto, com o objeto automaticamente vinculado ao primeiro argumento da função. Assim, o primeiro parâmetro obrigatório dos métodos de instância serve como this; este parâmetro é convencionalmente denominado self, mas pode ser denominado qualquer coisa.

Em métodos de classe (criados com o classmethoddecorador), o primeiro argumento se refere ao próprio objeto de classe e é convencionalmente chamado cls; eles são usados ​​principalmente para construtores herdáveis, onde o uso da classe como um parâmetro permite a subclasse do construtor. Em métodos estáticos (criados com o staticmethoddecorador), nenhum primeiro argumento especial existe.

Ferrugem

No Rust, os tipos são declarados separadamente das funções associadas a eles. As funções projetadas para serem análogas aos métodos de instância em linguagens orientadas a objetos mais tradicionalmente devem tomar explicitamente selfcomo seu primeiro parâmetro. Essas funções podem então ser chamadas usando o instance.method()açúcar da sintaxe. Por exemplo:

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

Isso define um tipo,, Fooque possui quatro funções associadas. O primeiro Foo::new(),, não é uma função de instância e deve ser especificado com o prefixo de tipo. Todos os três restantes aceitam um selfparâmetro de várias maneiras e podem ser chamados em uma Fooinstância usando a sintaxe de notação de ponto sugar, que é equivalente a chamar o nome da função qualificada pelo tipo com um selfprimeiro parâmetro explícito .

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

Auto

A linguagem do Self é nomeada após este uso de "self".

Xbase ++

Selfé estritamente usado nos métodos de uma classe. Outra maneira de se referir Selfé usar ::.

Veja também

Referências

Leitura adicional