这个编程功能的名称是什么?

时间:2011-03-22 22:10:32

标签: programming-languages dynamic static functional-programming

在某些动态语言中,我看到过这种语法:

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

基本上能够返回分支中的最后一个语句作为变量的返回值,不一定只返回方法返回,但也可以实现它们。

此功能的名称是什么?

这也可以用静态类型语言如C#实现吗?我知道C#有三元运算符,但我的意思是使用if语句,如上所示切换语句。

5 个答案:

答案 0 :(得分:7)

它被称为“条件分支是表达式”或“声明/表达式分裂的死亡”。

请参阅Conditional If Expressions

  
    

许多语言支持if表达式,它类似于if语句,但返回值作为结果。因此,它们是真正的表达式(评估为值),而不是语句(仅执行操作)。

  

也就是说,if (expr) { ... }表达式(可能是表达式语句,具体取决于上下文)语法语法就像?:是C,C#或Java等语言中的表达式一样。

这种形式在函数式编程语言中很常见(避免副作用) - 然而,它不是“函数式编程”本身并且存在于接受/允许“功能”的其他语言中喜欢语法“虽然仍然使用沉重的副作用和其他范例(例如Ruby)。

某些语言(如Perl)允许模拟此行为。也就是说,$x = eval { if (true) { "hello world!" } else { "goodbye" } }; print $x将显示“你好世界!”因为eval 表达式评估 中评估的最后一个值,即使if语法生成本身不是表达式。 ($x = if ...是Perl中的语法错误。)

快乐的编码。

答案 1 :(得分:2)

这是一个三元条件。

在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

保重, BECO。

PS。这个例子在你的问题的上下文中更有意义:

a=({
        int c;
        if(b==a)
            c=b+1;
        else
            c=a-1;
        c;
    });

答案 2 :(得分:2)

回答你的另一个问题:

  

这是否也可以用静态类型语言实现,例如C#?

语言是否支持?不可以实现?那种。

C# - 比如C ++,Java和所有类似的东西 - 都有表达式和语句。语句,如if-then和switch-case,不返回值,因此不能用作表达式。另外,稍微说一下,您的示例将myValue分配给字符串或整数,C#无法执行,因为它是强类型的。您要么必须使用object myValue,然后接受投射和装箱费用,请使用var myValue(仍然是静态类型,只是推断)或其他一些奇怪的聪明。

无论如何,如果if-then是一个声明,你如何在C#中做到这一点?你必须构建一个方法来实现if-then-else的目标。您可以使用静态方法作为bools的扩展,以模拟Smalltalk的方式:

public static T IfTrue(此bool值,Action doThen,Action doElse)    {       如果(值)           return doThen();       其他           return doElse();    }

要使用此功能,您需要执行类似

的操作
var myVal = (6 < 7).IfTrue(() => return "Less than", () => return "Greater than");
  • 免责声明:我没有测试过,所以由于拼写错误可能不太合适,但我认为原则是正确的。

新的IfTrue()函数检查它附加的布尔值,并执行传递给它的两个委托之一。它们必须具有相同的返回类型,并且都不接受参数(使用闭包,因此无关紧要)。

现在,你应该这样做吗?不,几乎可以肯定不是。它不是正确的C#做事方式,因此令人困惑,而且它的效率远低于使用if-then。你正在处理像IL指令这样的复杂的类和方法调用,.NET将在幕后构建以支持它。

答案 3 :(得分:1)

除了返回分支中最后一个表达式的值之外,可能(取决于语言)myValue被分配给匿名函数 - 或者在Smalltalk / Ruby中,{{3} }:

  

代码块(匿名函数)可以表示为文字值(它是一个对象,因为所有值都是对象。)

在这种情况下,由于myValue实际指向仅在使用myValue时调用的函数,因此该语言可能将它们实现为code blocks,这最初是功能语言。

因为闭包是带有自由变量的第一类函数,closures。但是,不会发生隐式返回;在C#中,他们只是匿名代表!考虑:

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

这也可以使用lambda表达式在C#中完成:

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

我意识到你的问题是询问隐含的返回值,但我试图说明这里不仅仅有“条件分支是表达式”

答案 4 :(得分:0)

  

这也可以静态实现   打字语言?

当然,可以静态和严格地检查所涉及的表达式的类型。似乎没有什么依赖于“if-as-expression”方法中的动态类型。

例如,Haskell - 一种严格的静态类型语言,具有丰富的类型系统:

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

(示例表达式可能更简单,我只想反映您的问题中的赋值,但演示该功能的表达式可能是simlpler:

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