Как называется эта функция программирования? - PullRequest
1 голос
/ 23 марта 2011

В некоторых динамических языках я видел такой синтаксис:

myValue = if (this.IsValidObject)
{
    UpdateGraph();
    UpdateCount();
    this.Name;
}
else
{
    Debug.Log (Exceptions.UninitializedObject);
    3;
}

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

Как называется эта функция?

Может ли это быть достигнуто и в статически типизированных языках, таких как C #?Я знаю, что в C # есть троичный оператор, но я имею в виду использование операторов if, переключение операторов, как показано выше.

Ответы [ 5 ]

7 голосов
/ 23 марта 2011

Это называется "условными ветвями, являющимися выражениями" или "смертью оператора / выражения".

См. Условные выражения If :

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

То есть if (expr) { ... } является выражением (возможно, выражение или выражение в зависимости от контекста) в грамматике языка, так же как ?: является выражением в таких языках, как C, C #или Java.

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

Некоторые языки, такие как Perl, позволяют моделировать это поведение.То есть $x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x будет отображать "Привет, мир!"потому что eval выражение соответствует последнему значению , вычисленному внутри , хотя само производство грамматики if не является выражением.($x = if ... - это синтаксическая ошибка в Perl).

Счастливое кодирование.

2 голосов
/ 23 марта 2011

Чтобы ответить на ваш другой вопрос:

Может ли это быть достигнуто и в статически типизированных языках, таких как C #?

Является ли это языком поддерживает?Нет. Может ли быть достигнуто ?Вид.

C # - как C ++, Java и все такое - имеет выражения и операторы.Операторы, такие как if-then и switch-case, не возвращают значений и поэтому не могут использоваться в качестве выражений.Кроме того, в качестве небольшого отступления в вашем примере myValue присваивается либо строке, либо целому числу, чего не может сделать C #, поскольку он строго типизирован.Вам нужно будет либо использовать object myValue, а затем принять расходы на кастинг и бокс, использовать var myValue (который все еще статический тип, только вывод) или какой-то другой причудливый ум.

В любом случае, так что еслиif-then это утверждение, как вы это делаете в C #?Вы должны были бы создать метод для достижения цели если-то-еще.Вы можете использовать статический метод как расширение для bools, чтобы смоделировать способ Smalltalk:

public static T IfTrue (это значение bool, Action doThen, Action doElse) {if (value) return doThen ();иначе return doElse ();}

Чтобы использовать это, вы должны сделать что-то вроде

var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
  • Отказ от ответственности: я не проверял ничего из этого, поэтому он может не совсем работать из-за опечаток, но я думаю,принцип верен.

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

Теперь, вы должны это сделать?Нет, почти наверняка нет.Это не правильный C # способ делать вещи, так что это сбивает с толку, и это гораздо менее эффективно, чем использование if-then.Вы торгуете чем-то вроде 1 IL-инструкции для сложного беспорядка классов и вызовов методов, которые .NET создаст за кулисами для поддержки этого.

2 голосов
/ 23 марта 2011

Это троичное условное выражение.

В C вы можете использовать, например:

printf("Debug? %s\n", debug?"yes":"no");

Отредактировано:

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

Например:

#include <stdio.h>

int main(void)
{
    int a=0, b=1;

    a=({
            printf("testing compound statement\n");
            if(b==a)
                printf("equals\n");
            b+1;
        });

    printf("a=%d\n", a);
    return 0;
}

Таким образом, имя выполняемой вами характеристики присваивается(локальная) переменная составной оператор.Теперь я думаю, что это поможет вам немного больше.Для получения дополнительной информации посетите этот источник: http://www.chemie.fu -berlin.de / chemnet / use / info / gcc / gcc_8.html

Береги себя, Беко.

PS.Этот пример имеет больше смысла в контексте вашего вопроса:

a=({
        int c;
        if(b==a)
            c=b+1;
        else
            c=a-1;
        c;
    });
1 голос
/ 23 марта 2011

В дополнение к возвращению значения последнего выражения в ветви, вполне вероятно (в зависимости от языка), что myValue присваивается анонимной функции - или в Smalltalk / Ruby, кодовые блоки * * 1004

Блок кода (анонимная функция) может быть выражен в виде литерального значения (которое является объектом, поскольку все значения являются объектами.)

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

Поскольку замыкания являются первоклассными функциями со свободными переменными, замыкания существуют в C # . Однако неявный возврат не происходит; в C # они просто анонимные делегаты! Рассмотрим:

Func<Object> myValue = delegate() 
{
    if (this.IsValidObject)
    {
        UpdateGraph();
        UpdateCount();
        return this.Name;
    }
    else
    {
        Debug.Log (Exceptions.UninitializedObject);
        return 3;
    }
};

Это также можно сделать в C # с помощью лямбда-выражений:

Func<Object> myValue = () => 
{
    if (this.IsValidObject) { ... }
    else                    { ... }
};

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

0 голосов
/ 02 апреля 2011

Может ли это быть достигнуто и в статически типизированных языках?

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

Например, Haskell - строгий статически типизированный язык с богатой системой типов:

$ ghci
Prelude> let x = if True then "a" else "b" in x
"a"

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

Prelude> if True then "a" else "b"
"a"

.)

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