Почему java / javascript / python заставляет использовать () после имени метода, даже если он не принимает аргументов? - PullRequest
5 голосов
/ 19 сентября 2010

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

Так что мне было интересно, есть ли хорошая логикаделая различие между вызовом свойств и методов объекта явным образом.

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

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

Кроме того, есть ли другие языки, где разница не очевидна?

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

ОБНОВЛЕНИЕ: Спасибо всем за потрясающие ответы!У меня есть всего около недели js и 1 день python, так что я понятия не имел, что вы можете ссылаться на функции, не вызывая их.Это потрясающе.У меня немного больше опыта работы с Java, так вот откуда я в основном пришел ... Может кто-нибудь придумать столь же убедительный аргумент, чтобы это имело место в Java, где вы не можете ссылаться на функции?Помимо того, что это очень явный язык, со всеми вытекающими отсюда преимуществами :).

Ответы [ 9 ]

13 голосов
/ 19 сентября 2010

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

Например,

def func():
    print "hello"
    return 10
a = func
a()

Очевидно, что a = func и a = func() имеют очень разные значения.

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

8 голосов
/ 19 сентября 2010

В таких языках, как Python и JavaScript, функции являются объектами первого класса. Это означает, что вы можете передавать функции так же, как вы можете передавать любое другое значение. Скобки после имени функции (() в myfunc()) фактически представляют собой оператор, точно так же как + или *. Вместо значения «добавить этот номер к другому номеру» (в случае +), () означает «выполнить предыдущую функцию». Это необходимо, потому что можно использовать функцию без ее выполнения. Например, вы можете сравнить ее с другой функцией, используя ==, или вы можете передать ее в другую функцию, например, в этом примере JavaScript:

function alertSomething(message) {
    alert(message);
}

function myOtherFunction(someFunction, someArg) {
   someFunction(someArg);
}

// here we are using the alertSomething function without calling it directly
myOtherFunction(alertSomething, "Hello, araneae!"); 

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

5 голосов
/ 19 сентября 2010

По крайней мере, в JS, потому что вы можете передавать функции.

var func = new Function();

можно тогда что-то вроде

 var f = func
 f()

поэтому 'f' и 'func' являются ссылками на функцию, а f () или func () - это вызов функции.

что не совпадает с

var val = f();

, который присваивает результат вызова переменной.

Для Java вы не можете передавать функции, по крайней мере, как в JS, поэтому нет причины, по которой язык должен требовать () для вызова метода. Но это то, что есть.

Я вообще не могу говорить за питона.

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

3 голосов
/ 19 сентября 2010

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

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

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

3 голосов
/ 19 сентября 2010

Я думаю, что вы сами ответили:

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

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

if (colorOfTheSky == 'blue')

против:

if (colorOfTheSky() == 'blue')

Мы можем сказать толькоглядя, что первая проверяет переменную с именем colorOfTheSky, и мы хотим знать, равно ли ее значение blue.Во втором мы знаем, что colorOfTheSky() вызывает функцию (метод), и мы хотим знать, равно ли ее возвращаемое значение blue.

Если бы у нас не было этого различия, это было бы крайне неоднозначно вситуации, подобные этой.

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

Кроме того, у вас, вероятно, есть проблемы с дизайном, если вы можете 'Расскажите разницу между вашими методами и вашими свойствами;как указывает другой ответ, методы и свойства играют разные роли.Более того, хорошей практикой является то, что ваши имена методов должны быть действиями, например, getPageTitle, getUserId и т. Д., А ваши свойства должны быть существительными, например, pageTitle, userId.Они должны быть легко расшифрованы в вашем коде как для вас, так и для всех, кто придет позже и прочитает ваш код.

2 голосов
/ 19 сентября 2010

Разница не всегда очевидна в VBA. Это вызов Sub (т.е. метод без возвращаемого значения), который не принимает параметров (все примеры из Excel):

Worksheets("Sheet1").UsedRange.Columns.AutoFit

тогда как он обращается к атрибуту, а затем передает его в качестве параметра:

MsgBox Application.Creator

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

Application.Goto Worksheets("Sheet2").Range("A1")

но необходимы, если используется возвращаемое значение:

iRows = Len("hello world")
2 голосов
/ 19 сентября 2010

В Java я могу придумать две причины, по которым требуется ():

1) У Java была особая цель: иметь синтаксис, подобный C / C ++, чтобы программистам на C и C ++ было легко изучать язык. И C, и C ++ требуют скобок.

2) Синтаксис Java, в частности, требует, чтобы круглые скобки устраняли неоднозначность ссылки на атрибут или локальный от вызова метода. Это потому, что имена методов и атрибуты / локальные имена объявляются в разных пространствах имен. Итак, следующее является законной Java:

public class SomeClass {
    private int name;
    private int name() { ... }

    ...

    int norm = name;  // this one
}

Если () не требуется для вызова метода, компилятор не сможет определить, присваивает ли помеченный оператор («этот») значение атрибута name или результат вызова name() метод.

2 голосов
/ 19 сентября 2010

Потому что ссылка и вызов метода - это две разные вещи.Рассмотрим X.method как метод class X и x как экземпляр X, поэтому x.method == 'blue' никогда не сможет быть истинным, потому что методы не являются строками.

Вы можете попробовать это: напечатать метод объекта:


>>> class X(object):
...   def a(self):
...     print 'a'
...
>>> x=X()
>>> print x.a
<bound method X.a of <__main__.X object at 0x0235A910>>

1 голос
/ 19 сентября 2010

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

Foo.Bar будет означать, что он вернет значение, например строку, без больших накладных расходов..

Foo.Bar () (или, более вероятно, Foo.GetBar ()), с другой стороны, подразумевает необходимость извлечения значения для «Bar», возможно, из базы данных.

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

Кстати, во всех известных мне языках различие в синтаксисе явное, но за кадром свойствачасто рассматривается как просто вызов специальных методов.

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