如何编写`isEven()`函数作为可调用函数?

huangapple go评论50阅读模式
英文:

How to write isEven() function as callable function?

问题

我正在学习 PHP,通过审查一些完整的 PHP 项目。 (我知道这不是一个好的学习方法,但我的目标不是成为 PHP 程序员!)不管怎样,我遇到了以下对我来说有点奇怪的函数:

function filterIt($filter): callable {
    return function ($value) use ($filter) {
        return filter_var($value, $filter) !== false;
    };
}

我不知道这个函数是做什么的,为什么它要以一个函数嵌套在另一个函数内部的方式编写!内部函数返回某些东西,主函数也是。为什么我们需要这样复杂的函数?或者也许可以简化它?

因此,出于这个原因,我想编写一个类似上面的 isEven() 函数,使其成为可调用函数。但我毫无头绪!

我不知道那个函数是做什么的,但通过模仿它,我写了如下的函数:

function isEven($num): callable {
    return function () use ($num) {
        return $num % 2 == 0;
    };
}

我无法使用 var_dumpprint_r 进行调试。

英文:

I am learning PHP using reviewing some complete PHP projects. (I know that this is a bad way, but my goal is not to be a PHP programmer!) Anyway, I faced with the following function that is weird a little to me:

function filterIt($filter): callable {
    return function ($value) use ($filter) {
        return filter_var($value, $filter) !== false;
    };
}

I don't know what this function do and why it has been witter in such a way that a function is inside of another function! inner function returns something and main function also. Why we need such complicated function? or maybe one can make it simpler?

For this reason I want to write isEven() function as callable function like above. But I have no idea!

I don't know what that function do, but by mimicking from that:

function isEven($num): callable {
    return function () use ($num) {
        return $num % 2 == 0;
    };
}

I couldn't debug this using var_dump or print_r .

答案1

得分: 0

不确定你在测试中如何调用这个函数,但由于这个函数实际上返回了一个可调用对象,所以你可以在运行它时像这样进行调试:


function isEven($num): callable {
    return function () use ($num) {
        return $num % 2 == 0;
    };
}

var_dump(isEven(14)());

英文:

Not sure how you are calling this in you're test, but as the function is actually returning a callable you would be able to debug it once you run it like this:

<?php

function isEven($num): callable {
    return function () use ($num) {
        return $num % 2 == 0;
    };
}

var_dump(isEven(14)());

答案2

得分: 0

IMO,“filterIt()”函数的摘要是“给我一个基于$filter的匿名函数,然后可能将该可调用函数传递到其他地方以进行应用。我敢说作者编写这个函数是为了简化,这样他们不需要反复编写$filter的不同值的匿名函数定义。

以下是这种行为的简化示例:

class ExampleCollection {
    protected $filters = [];
    
    public function __construct(protected array $items) {}
    
    public function addFilter(callable $filter) {
        $this->filters[] = $filter;
    }
    
    public function getFiltered() : Generator {
        foreach ($this->items as $item) {
            foreach ($this->filters as $filter) {
                if ($filter($item)) {
                    continue 2;
                }
            }
            yield $item;
        }
    }
}

function makeMultipleFilter(int $value) : callable {
    return function ($a) use ($value) {
        return $a % $value === 0;
    };
}

$c = new ExampleCollection([1,2,3,4,5,6,7,8,9,10]);

// 添加过滤器以排除3和4的倍数
$c->addFilter(makeMultipleFilter(3));
$c->addFilter(makeMultipleFilter(4));

foreach ($c->getFiltered() as $item) {
    printf("Got: %d\n", $item);
}

输出:

Got: 1
Got: 2
Got: 5
Got: 7
Got: 10

但我同意Chris Haas的评论,作者的意图并不总是显而易见,最好向他们询问,如果可能的话。此外,即使有卓越的人写过代码,也不是所有代码都是值得效仿的。每个人有时都会陷入困境,不得不采取一个令人困惑和/或丑陋的代码片段来解决问题。这并不是说这就是那样,尽管第一次阅读时它确实有点令人困惑。

英文:

IMO the summary of the filterIt() function is "give me an anonymous function that filters based on $filter", and then that callable is likely passed somewhere else to be applied. I would venture to guess that the author wrote this function as a shorthand so that they did not need to write out the anonymous function definition over and over for different values of $filter.

Below is a simplified example of such behaviour:

class ExampleCollection {
    protected $filters = [];
    
    public function __construct(protected array $items) {}
    
    public function addFilter(callable $filter) {
        $this->filters[] = $filter;
    }
    
    public function getFiltered() :\Generator {
        foreach($this->items as $item) {
            foreach($this->filters as $filter) {
                if( $filter($item) ) {
                    continue 2;
                }
            }
            yield $item;
        }
    }
}

function makeMultipleFilter(int $value) :callable {
    return function($a)use($value) {
        return $a % $value === 0;
    };
}

$c = new ExampleCollection([1,2,3,4,5,6,7,8,9,10]);

// add filters to exclude multiples of 3 and 4
$c->addFilter(makeMultipleFilter(3));
$c->addFilter(makeMultipleFilter(4));

foreach($c->getFiltered() as $item) {
    printf("Got: %d\n", $item);
}

Output:

Got: 1
Got: 2
Got: 5
Got: 7
Got: 10

But I agree with Chris Haas' comment that the author's intent is not always obvious and is best asked of them, if possible. Further to that, not all code is exemplary, even if someone exemplary happens to have written it. Everyone writes themselves into a corner sometimes and has to resort to a confusing and/or ugly piece of code to get around it. Which is not to say that this is what that is, though it is somewhat confusing on first read.

huangapple
  • 本文由 发表于 2023年2月14日 04:57:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定