为了账号安全,请及时绑定邮箱和手机立即绑定

在不重复函数调用和创建额外变量的情况下找到第一个匹配项。有可能吗?

在不重复函数调用和创建额外变量的情况下找到第一个匹配项。有可能吗?

PHP
莫回无 2021-08-28 15:51:54
我想从内部按顺序调用函数 B 和 C 的函数 A 中获得第一个成功的结果。这里的关键点是 - DRY。这意味着我不想引入新变量(例如保持前一个函数调用的结果状态 - 见坏示例#1),我不想重复我的动作(例如两次调用同一个函数 - 见坏示例#2)。示例代码是用 PHP 编写的,但我不沉迷于 PHP,任何语言都可以接受。OOP,功能性,在这里无关紧要。到目前为止我发现的可能导致解决方案的概念是使用 Maybe ( https://marcosh.github.io/post/2017/06/16/maybe-in-php.html ),有些人还建议使用 nil ( https://clojure.org/reference/data_structures#nil ) 作为返回类型。但是,我还没有足够的工作示例。我想知道这个解决方案是否可行,我什至开始阅读名为“注释图灵”的书,希望能找到一些指向问题或限制的链接......坏例子#1(额外变量):A() {  $B = B();  if($B !== null) {    return B();  }  return C();}坏例子#2(额外调用):A() {  if(B() !== null) {    return B();  }  return C();}这里的关键点 - DRY: - 我不希望引入任何额外的变量(坏例子#1)。- 我不希望任何函数运行两次(坏例子#2)。是否可以在不重复调用和/或将状态保存到额外变量的情况下编写此类代码?如果是的话 - 我想看看。如果没有,那么我想有一个有效的证明,这是根本不可能写的。
查看完整描述

2 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

这是使用空合并运算符的PHP 7 或更高版本:


<?php

function a()

{

    return (b() ?? c());

}


function b()

{

    return null;

}


function c()

{

    return 'result from c';

}


var_dump(a());


查看完整回答
反对 回复 2021-08-28
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

我将展示 JavaScript 中的示例,因为我更熟悉它。这些将是我们的B和C功能:


function B() {

    return Math.random() > 0.5 ? 'B' : null;

}


function C() {

    return 'C';

}

1. 依靠逻辑短路评估 or

function A() {

    return B() || C();

}

请注意,这与您想要的有点不同,因为B()只有当它是非假值时才会返回结果。


2. 使用效用函数

function firstNonNullResult(functions) {

    for (const f of functions) {

        const result = f();

        if (result !== null) {

            return result;

        }

    }

}


function A() {

    return firstNonNullResult([B, C]);

}

3. 使用惰性求值

某些语言,例如 Haskell,在需要结果之前不会计算表达式,这允许您编写类似find isJust [B, C], whereC仅在不B返回任何内容的情况下进行计算的内容。


在 JavaScript 或 PHP 中,您可以使用生成器实现类似的效果。


function* map(items, fn) {

    for (const item of items) {

        yield fn(item);

    }

}


function find(items, predicate) {

    for (const item of items) {

        if (predicate(item)) {

            return item;

        }

    }

}


function call(fn) {

    return fn();

}


function A() {

    return find(map([B, C], call), x => x !== null)    

}


查看完整回答
反对 回复 2021-08-28
  • 2 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信