是否有任何主要语言有“或如果”/“如果”有条件,如果没有,为什么不呢?

时间:2014-03-04 15:48:48

标签: programming-languages conditional-statements

我的一位朋友正在学习编程,他问我为什么没有“and if”/“also if”/“or if”声明(非独占或),其中可以满足具有独立结果的多个独立测试条件,这将阻止任何“else”条件触发。 修改:我认为我选择“或”可能是一个错误的关键字,因为or关键字通常是懒惰地评估,因此第二个分支永远不会触发。我正在谈论的是所有真实条件的事情,但是如果or if中有没有真实条件,那么你继续else / elif分支。

这是一个例子(使用python语法):

if a:
    print('a evaluates True')
orif b:
    print('b evaluates True')
else:
    print('Both a and b evaluate False')

这与elif的不同之处在于,如果 ab都为真,则输出结果为:< / p>

a evaluates True
b evaluates True 

而在elif中,该条件的输出将是:

a evaluates True

我接受了“我已经编程多年”的帽子并且开始解释,“好吧,当然没有orif声明,因为......”,但我无法想出一个好理由。这个概念的一个很好的例子是fizzbuzz,其中要求您打印1到100之间的所有数字,但是所有可被3整除的数字被fizz替换,所有可被5整除的数字被{{ 1}}和所有可被3和5整除的数字替换为buzz。使用“fizzbuzz”语法,可以使用单个条件来完成:

orif

但是如果没有它,你会遇到一些不那么优雅的东西,无论是转换到三个条件还是至少一个额外的模数评估:

for x in range(1, 100):
    outstr = ""
    if x%3 == 0:
        outstr += "fizz"
    orif x%5 == 0:
        outstr += "buzz"
    else:
        outstr = x

    print(x)

或者您可以通过提前存储来避免额外的模运算:

for x in range(0, 100):
    outstr = ""
    if x%3 == 0:
        outstr += "fizz"

    if x%5 == 0:
        outstr += "buzz"

    if not x%15 == 0:       # Could also be not (x%3 and x%5)
        outstr = x

    print(x)

显然还有其他方法可以实现这一点,但它们都不像“orif”结构那样直观。回想一下,我注意到这是我实际上遇到的很多次,我有许多条件具有不同的效果,每个条件都需要进行评估,并且默认条件是如果满足 none ,则会发生。我通常通过在每个单独的条件中使用恼人的“flag”变量来“解决”这个问题:

for x in range(0, 100):
    outstr = ""
    fizz = (x%3 == 0)
    buzz = (x%5 == 0)

    if fizz:
        outstr += "fizz"

    if buzz:
        outstr += "buzz"

    if not (fizz or buzz):
        outstr = x

    print(x)

显然,这是一种非常不优雅和烦人的方式,“orif”解决了另一个问题。因此,鉴于“OneConditionMet = False if a: # Do the "a" stuff OneConditionMet = True if b: # Do the "b" stuff OneConditionMet = True # ... if n: # Do the "n" stuff OneConditionMet = True if not OneConditionMet: # Do the default behavior. ”的所有这些明确原因,我很震惊地发现Wikipedia article on conditionals中没有任何提及任何相似内容。这让我觉得我错过了一些基本的东西,为什么这不起作用。我能想到的唯一原因是,如上所述,评估需要稍微不那么懒,因为即使满足第一个“if”条件,它也需要检查是否出现“或if”分支。但是,这是一个非常容易解决的问题,因为你可以这么做,这样如果你在条件树中有任何orif语句,那么所有 or if语句需要是if语句,如下:

or if

所以,有一个问题 - 我是否遗漏了与此基本相同的东西?我错过了一些原因,为什么它根本不可行,或者这只是一个巨大的错失机会?

3 个答案:

答案 0 :(得分:1)

您要求的内容可替代地描述为模式匹配或决策表。即便如此,在假分支上获得正确的行为并不容易,而且我没有看到任何语言正是如此。

模式匹配语言(如awk)会触发与模式匹配的每个规则。您需要一些额外的代码来记录是否有任何规则被触发,如果没有则触发else规则。

决策表软件至少在30年前很受欢迎(作为预处理器)。基本上,您将测试和操作放在一个表中,系统会分析剩下的内容,以便执行默认操作。

就个人而言,我不认为它有用。在管理复杂的if测试集时存在实际问题,我不认为这个单一特性会解决其中的许多问题。在很多这些情况下,您可以自然地确保检测到else情况,因为某些变量从未被触及过。有更难的组合需要认真规划以避免完全混淆。

BTW使用'andif'和'orif'是无益的。他们确实让人完全想到别的东西。

答案 1 :(得分:0)

我不知道。但...

首先要知道你的'parallel if'几乎完全等同于标准'if'的序列。唯一的区别就是else子句。如果谓词计算很昂贵,你可以随时缓存它(就像你的modulo示例中那样)

当我们谈论命令式/ OOP时,每个人都试图使用继承和一些功能习惯用法(比如各种'可选')来简单地删除分支。据说只有switch/case语句才允许在工厂内部使用,它们应该没有逻辑,除了返回某种枚举之外什么都不做。

当我们谈论函数式编程时,似乎这个结构更没用。功能程序往往是功能组合。每个表达式应该返回一个值,并且(几乎)没有副作用。所以这个构造将丢弃几乎所有分支的返回值,并且仅对应该被隔离的非纯代码有用。

当我试图从日常工作中回忆起我的代码时,我真的找不到一个我想要使用它的地方。也许在通用语言中根本不需要它。但你总是可以实现宏

答案 2 :(得分:-1)

我认为orif构造不适合C,因为它太复杂了。所有现有的C语句都具有简单的语法,并且只有一个子语句。例如在for中你有

for (clause; expression; expression)
    statement

即使是最复杂的切换,使用一个子语句和使用case作为类似于goto标签的标签的技巧。 orif将会非常不同 - 它需要任意数量的子语句及其相应的条件。

从这个角度来看,orif将是一个与所有现有C语句完全不同的野兽。今天,尽管许多流行的语言提供了C语言中没有的各种结构,但循环语句和条件语句等基本语句在很多情况下都是从C继承而来的(显然仍有变化)。我为C提出的论点也适用于许多其他语言。 (并非所有,因为例如Python有类似的elif。)我想这至少部分解释了为什么没有orif