Подтвердить что ты не робот

Пишут "это". перед экземпляром переменной и методами хороший или плохой стиль?

Один из моих противных (?) навыков программирования в С++ и Java всегда должен предшествовать вызовам или обращениям к членам с помощью this. Например: this.process(this.event).

Несколько моих учеников прокомментировали это, и мне интересно, учат ли я вредным привычкам.

Мое рассуждение:

  • Делает код более удобочитаемым. Легче отличать поля от локальных переменных.
  • Делает проще отличать стандартные вызовы от статических вызовов (особенно в Java)
  • Заставляет меня помнить, что этот вызов (если конечная цель не является окончательной) может закончиться другой целью, например, в переопределяемой версии в подклассе.

Очевидно, что это имеет нулевое воздействие на скомпилированную программу, это просто читаемость. Так я делаю это более или менее читаемым?

Примечание. Я превратил его в CW, так как на самом деле нет правильного ответа.

4b9b3361

Ответ 1

Я думаю, что это менее читаемо, особенно в средах, где поля выделяются иначе, чем локальные переменные. Единственный раз, когда я хочу видеть "this", когда требуется, например:

this.fieldName = fieldName

При назначении поля.

Тем не менее, если вам почему-то нужно каким-то образом дифференцировать поля, я предпочитаю "this.fieldName" другим соглашениям, например "m_fieldName" или "_fieldName"

Ответ 2

Это очень субъективная вещь. Microsoft StyleCop имеет правило, требующее квалификатор this. (хотя он связан с С#). Некоторые люди используют подчеркивание, некоторые используют странные венгерские обозначения. Я лично квалифицирую членов с помощью this., даже если это явно не требуется, чтобы избежать путаницы, потому что есть случаи, когда он может сделать один код более читабельным.

Вы также можете проверить этот вопрос:
Какой префикс вы используете для переменных-членов?

Ответ 3

Я никогда не видел этот стиль, пока не присоединился к моему нынешнему работодателю. В первый раз, когда я это увидел, я подумал: "Этот идиот не имеет понятия, а языки Java/OO вообще не его сильный костюм", но оказывается, что это регулярно возникающее несчастье здесь и является обязательным стилем на нескольких проектах, хотя эти проекты также используют

if (0 == someValue)
{
    ....
}

подход к выполнению условных выражений, т.е. помещение константы в тест, чтобы вы не рискули писать

if (someValue = 0)

случайно - общая проблема для кодеров C, которые игнорируют свои предупреждения о компиляторе. Дело в том, что в Java это просто недействительный код и будет выгружен компилятором, поэтому они фактически делают свой код менее интуитивным без каких-либо преимуществ.

Поэтому для меня, далеки от того, чтобы показать "автор кодируется с помощью преданного мыслительного процесса", эти вещи поражают меня, как скорее, от человека, который просто придерживается правил, которые кто-то сказал им однажды, без допроса их или зная причины правил в первую очередь (и поэтому там, где правила не должны применяться).

Причины, о которых я слышал, в основном сводятся к "этой лучшей практике", обычно ссылающейся на Josh Bloch Эффективная Java, которая имеет огромное влияние здесь. На самом деле, однако, Блох даже не использует его там, где даже я думаю, что он, вероятно, должен был бы облегчить читаемость! Опять же, похоже, это нечто большее, что делают люди, которым говорят это делать и не знают, почему!

Лично я склонен больше согласиться с тем, что говорит Брюс Эккель в "Мышление на Java" (3-е и 4-е издания):


'Некоторые люди будут одержимо помещать этот перед каждым вызовом метода и ссылкой на поле, утверждая, что он делает его "более ясным и более явным". Не делай этого. Там есть причина, по которой мы используем языки высокого уровня: они делают что-то для нас. Если вы установите этот, когда это не обязательно, вы будете путать и раздражать всех, кто читает ваш код, так как весь остальной код, который они прочитали, не будет использовать this везде. Люди ожидают, что этот будет использоваться только тогда, когда это необходимо. После последовательного и простого стиля кодирования экономится время и деньги.


footnote, p169, Думая на Java, 4-е издание

Довольно. Меньше, больше, люди.

Ответ 4

3 причины (костюм Nomex ВКЛ)

1) Стандартизация

2) Считываемость

3) IDE

1) Biggie Не является частью стиля кода Sun Java.

(Нет необходимости иметь какие-либо другие стили для Java.)

Так что не делайте этого (на Java.)

Это часть синей фигуры Java: она всегда одинакова везде.

2) Считываемость

Если вы хотите this.to иметь this.this перед each.other this.word; вы действительно это. По-видимому, это улучшает эту удобочитаемость?

Если в классе слишком много методов или переменных, чтобы узнать, является ли это членом или нет... refactor.

Вы только имеете переменные-члены, и у вас нет глобальных переменных или функций в Java. (В других langunages вы можете иметь указатели, переполнение массива, исключенные исключения и глобальные переменные, наслаждайтесь.)

Если вы хотите узнать, находится ли метод в родительском классе классов или нет... не забудьте положить @Override в свои объявления и дать компилятору рассказать вам, если вы не переопределяете правильно. super.xxxx() является стандартным стилем в Java, если вы хотите вызвать родительский метод, иначе оставьте его.

3) IDE Любой, кто пишет код без IDE, который понимает язык и дает схему на боковой панели, может сделать это на своем собственном никеле. Понимая, что если он не "чувствителен к языку", вы попадаете в ловушку в 1950-х годах. Без GUI: Ловушка в 50-х.

Любой достойный IDE или редактор сообщит вам, откуда находится функция/переменная. Даже оригинальный VI (< 64kb) будет делать это с помощью CTags. Просто нет оправдания для использования дерьмовых инструментов. Хорошие раздаются бесплатно!

Ответ 5

Иногда мне нравится писать такие классы:

class SomeClass{
    int x;
    int y;

    SomeClass(int x, int y){
        this.x = x
        this.y = y
    }
}

Это упрощает определение аргумента, задающего член.

Ответ 6

Более читаемый, я думаю. Я делаю это по самым разным причинам.

Ответ 7

Я считаю, что меньше. Чем больше ненужных подробностей, которые у вас есть в коде, тем больше проблем у людей будет поддерживать его. При этом важно иметь четкое и последовательное поведение.

Ответ 8

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

Во-вторых, нет возможности иметь функцию с тем же именем глобального или из какого-либо пространства имен, которое получает "использование" в конфликт. Поэтому, если есть конфликт, исходный автор кода наверняка будет знать, какую функцию они вызывают.

Предположим, что если есть конфликты пространства имен, нарушается какое-то другое правило чистого кодирования, но никто не идеален. Поэтому я чувствую, что любое правило, которое не мешает производительности, может уменьшить ошибки (хотя и незначительный потенциал) и может облегчить будущую задачу устранения неполадок, является хорошим правилом.

Ответ 9

Существует хорошая техническая причина, чтобы предпочесть использовать или избегать this - они не всегда эквивалентны.

Рассмотрим следующий код:

int f();

template <typename T>
struct A
{
  int f();
};

template <typename T>
struct B : A<T>
{
  int g()
  {
    return f();
    return this->f();
  }
};

Теперь в B<T>::g() есть два вызова f(). Можно было бы ожидать, что он вызовет A<T>::f(), но будет только второй. Первый вызовет ::f(). Причина этого в том, что, поскольку A<T> зависит от T, поиск обычно не находит его. this, будучи указателем на B<T>, также зависит от T, поэтому, если вы его используете, поиск будет задерживаться до тех пор, пока не будет создан экземпляр B<T>.

Обратите внимание, что это поведение может отсутствовать на некоторых компиляторах (в частности, MSVC), которые не реализуют двухфазный поиск имени, но тем не менее это правильное поведение.

Ответ 10

Я использую this по крайней мере по двум причинам:

Ошибочные причины

Мне нравится иметь последовательные стили кода при кодировании в С++, C, Java, С# или JavaScript. Я придерживаюсь того же стиля кодирования, в основном вдохновленного Java, но вдохновленного другими языками.

Мне нравится также поддерживать согласованность внутри моего кода на одном языке. Я использую typename для параметров типа шаблона вместо class, и я никогда не проигрываю микшер с этими двумя. Это означает, что я ненавижу это, когда нужно добавить this в какой-то момент, но избегайте его вообще.

Мой код довольно verbous. Мое имя метода может быть длинным (или нет). Но они всегда используют полные имена и никогда не уплотняют имена (т.е. getNumber(), а не getNbr()).

Эти причины недостаточно хороши с технической точки зрения, но тем не менее это мой способ кодирования, и даже если они не делают ничего хорошего, они не делают ничего (много) зла. На самом деле, в кодовой базе, над которой я работаю, существует более чем достаточно исторических анти-шаблонов, написанных другими, чтобы они подвергли сомнению мой стиль кодирования.

К тому времени, когда они научатся писать "исключение" или "класс", я подумаю обо всем этом, снова...

Реальные причины

Хотя я ценю работу компилятора, есть некоторые двусмысленности, которые я хотел бы сделать неоднозначными ООН.

Например, я (почти) никогда не использую using namespace MyNamespace. Я либо использую полное пространство имен, либо использую псевдоним из трех букв. Мне не нравятся двусмысленности, и мне не нравится, когда компилятор внезапно говорит мне, что слишком много функций "печатают", сталкиваясь друг с другом.

Именно поэтому я префикс Win32-функций глобальным пространством имен, т.е. всегда пишу ::GetLastError() вместо GetLastError().

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

Это, по-видимому, может быть использовано как аргумент против перегрузки метода, возможно. Но это было бы очевидно. Если я пишу перегруженные методы, я хочу, чтобы компилятор разрешил неоднозначность во время компиляции. Если a не записывает ключевое слово this, это не потому, что я хочу, чтобы компилятор использовал другой символ, чем тот, который я имел в виду (например, функция вместо метода или что-то еще).

Мое заключение?

В целом, эта проблема в основном связана с стилем и с подлинными техническими причинами. Я не хочу смерти кого-то, не пишущего this.

Что касается цитаты Брюса Эккеля из его "Мышлой Java"... Меня не впечатлило смещенное сравнение Java/С++, которое он продолжает делать в своей книге (и отсутствие сравнения с С#, как ни странно), поэтому его личное точка зрения this, сделанная в сноске... Ну...

Ответ 11

Неплохая привычка. Я не делаю этого сам, но это всегда плюс, когда я замечаю, что кто-то другой делает это в обзоре кода. Это признак качества и удобочитаемости, который показывает, что автор кодирует выделенный процесс мышления, а не просто взламывает.

Ответ 12

Я бы сказал, что самое главное - это последовательность. Существуют разумные аргументы за и против, поэтому в основном это вопрос вкуса при рассмотрении того, какой подход.

Ответ 13

Люди Python делают это все время, и почти все они предпочитают это. Они пишут "я" вместо 'this'. Есть способы обойти это, вводя явное "я" , но консенсус в том, что явное "я" имеет важное значение для понимания метода класса.

Ответ 14

Мне нужно присоединиться к "включать этот" лагерь; Я не делаю этого последовательно, но с точки зрения обслуживания преимущества очевидны. Если сопровождающий не использует IDE по какой-либо причине и, следовательно, не имеет особо выделенных полей и методов, то они находятся в мире боли прокрутки.

Ответ 15

"читаемость"

Я нашел полезным использование "this" специально, если не использовать IDE (небольшие быстрые программы)

Whem мой класс достаточно велик, чтобы делегировать некоторые методы новому классу, заменив "this" на "otherRef" очень простым с помощью самого простого текстового редактора.

т

//Before
this.calculateMass();
this.perfornmDengerAction();
this.var = ...
this.other = ...

После "refactor"

// after
this.calculateMass();
riskDouble.calculateMass();
riskDouble.setVar(...);
this.other = ... 

Когда я использую IDE, я обычно не использую его. Но я думаю, что это делает вас более сложным способом, чем просто использовать метод.

class Employee {

        void someMethod(){
             // "this" shows somethings odd here.
             this.openConnectino() ; // uh? Why an employee has a connection???
             // After refactor, time to delegate.
             this.database.connect(); // mmhh an employee might have a DB.. well.. 
         }
     ... etc....
}

Самое главное, как всегда, состоит в том, что, если команда разработчиков решит его использовать или нет, это решение соблюдается.

Ответ 16

С точки зрения .Net некоторые инструменты анализа кода, которые я использовал, видели "this" и сразу же завершили, что метод не может быть статическим. Это может быть что-то тестировать с Java, но если он делает то же самое, вы можете не заметить некоторые улучшения производительности.

Ответ 17

Я всегда использовал это... Тогда коллега указал мне, что в целом мы стремимся уменьшить ненужный код, так что не должно ли это правило применяться и здесь?

Ответ 18

Если вы собираетесь удалить необходимость добавления этого. перед переменными-членами, инструменты статического анализа, такие как checkstyle может быть бесценным при обнаружении случаев, когда переменные-члены скрывают поля. Удалив такие случаи, вы можете удалить необходимость использования этого в первую очередь. При этом я предпочитаю игнорировать эти предупреждения в случае конструкторов и сеттеров, а не придумывать новые имена для параметров метода:).

Что касается статических переменных, я считаю, что большинство достойных IDE будут выделять их, чтобы вы могли рассказать их обособленно. Он также платит за использование соглашения об именах для таких вещей, как статические константы. Инструменты статического анализа могут помочь здесь, применяя соглашения об именах.

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

Ответ 19

Я предпочитаю режим локального назначения, описанный выше, но не для вызовов локальных методов. И я согласен с тем, что "консистенция - это самый важный аспект". Я нахожу это. Что-то более читаемое, но я считаю, что кодирование еще более удобочитаемо.

public void setFoo(String foo) {
    this.foo = foo; //member assignment
}

public doSomething() {
    doThat(); //member method
}

У меня есть коллеги, которые предпочитают:

public void setFoo(String foo) {
    _foo = foo;
}

Ответ 20

менее читаемый, если, конечно, ваши ученики все еще не находятся на терминалах с зелеными экранами, таких как студенты здесь... элита имеет синтаксический стиль.

Я только слышал слух, что у них тоже есть инструменты для рефакторинга, а это значит, что вам это не нужно. для поиска и замены, и они могут удалить эти досадные избыточные этики одним нажатием клавиши. по-видимому, эти инструменты могут даже разделить методы, чтобы они были хорошими и короткими, как они должны были начинаться с большей части времени, а затем это было очевидно даже для зеленого screener, которые являются полями.