2016-06-09 3 views
4

я столкнулся в некотором коде следующего вызова:метод Delphi вызов с последующим()

SQLParser.Parse(qry.SQL.Text)().GetWhereClause

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

TSQLParser = class 
    public 
    class function Parse(const ASQL: string): ISmartPointer<TSQLStatement>; 

    TSQLStatement = class 
    function GetWhereClause: string; 

и

ISmartPointer<T> = reference to function: T; 
+1

Тот факт, что Delphi позволяет выполнять вызовы функций без парсеров (для функций без аргументов), на мой взгляд, является большой слабостью. Эта удобная функция приводит к двусмысленности. Не только двусмысленность читателю кода, но и компилятору. Когда у компилятора есть выражение процедурного типа, как он знает, хотите ли вы ссылаться на это процедурное значение или вызвать процедуру? –

+2

@David: вы можете использовать @ с процедурным типом. Это даст вам процедурное значение, а не результат его вызова. OTOH, если вы добавите круглые скобки, вы получите результат вызова. Вызов процедуры без parens является наследием старых дней Pascal, когда это еще не проблема. –

+0

@RudyVelthuis Я понимаю историю. Тем не менее, это действительно не помогает нам. И использование '@' - очень плохая идея. Он дает нетипизированный указатель на код. Не используется для методов anon, не используется для методов объектов. Пожалуйста, никогда не предлагайте общее использование '@' с процедурными типами. Его использование очень ограничено особыми обстоятельствами. –

ответ

12

Функция Анализировать возвращает ссылку на функцию. Вы можете вызвать эту функцию. Более длинная эквивалентная форма будет:

var 
    FunctionReference: ISmartPointer<TSQLStatement>; 
    SQLStatement: TSQLStatement; 
begin 
    { Parse returns a reference to a function. Store that function reference in FunctionReference } 
    FunctionReference := TSQLParser.Parse(qry.SQL.Text); 
    { The referenced function returns an object. Store that object in SQLStatement } 
    SQLStatement := FunctionReference(); 
    { Call the GetWhereClause method on the stored object } 
    SQLStatement.GetWhereClause(); 

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