如何在PHP中传递标签?
这个故事的背景很长,所以简而言之——我知道后藤很糟糕,但我别无选择,因为。。。PHP缺少逗号运算符 我有这样的模式——以标签形式给出入口点的正则函数,其中有一个小lambda,它需要如何在PHP中传递标签?,php,lambda,goto,Php,Lambda,Goto,这个故事的背景很长,所以简而言之——我知道后藤很糟糕,但我别无选择,因为。。。PHP缺少逗号运算符 我有这样的模式——以标签形式给出入口点的正则函数,其中有一个小lambda,它需要转到该入口点。类似这样的内容(错误代码): 我不能跳过函数边界,所以我的下一个想法是从lambda返回标签,并将其用作goto的“值”。大概是这样的: function water() { _Entry_point_2_0: // ... some code goto (functio
转到该入口点。类似这样的内容(错误代码):
我不能跳过函数边界,所以我的下一个想法是从lambda返回标签,并将其用作goto的“值”。大概是这样的:
function water()
{
_Entry_point_2_0:
// ... some code
goto (function() { /*...*/ ;return '_Entry_point_2_0';})();
// ... some code
}
$k = 10;
$f = function() use (&$k) { /*...*/ ; return $k !== 0; };
do {
// some code
} while ( $f() );
这是行不通的。将整个goto
计算为字符串eval('goto\u Entry\u point\u 2\u 0;')
也不起作用
最疯狂的是我提前知道了标签,所以你可以问我为什么不能这样编写整个函数:
function water()
{
_Entry_point_2_0:
// ... some code
(function() { /*...*/ ;})();
goto _Entry_point_2_0;
// ... some code
}
问题出在逻辑上——现在执行lambda和生成两个表达式,而不是一个。我需要在一个表达式中实现它——执行lambda和goto必须打包在一个表达式中
我也不能递归调用main函数,因为这是本文的重点,以避免递归调用:-)
实现这一目标的其他方法是什么
更新1也许我要重新措辞——我想通过goto实现的是继续我的_功能
。在内部函数(即lambda)的边界处执行
更新2主要目标是循环主要功能,因此它几乎等同于:
function water()
{
_Entry_point_2_0: while (true)
{
// ... some code
continue (function() { /*...*/ ; return '_Entry_point_2_0'; })();
// ... some code
}
}
“几乎”是因为两个原因。与以前一样,我仍然存在标签问题,而且现在我还存在向循环中添加break
s的问题。您可以使用递归:
function myFunc($i = 0) {
if ($i < 10) { //or any other logic to prevent "infinite loop"
//Main code
myFunc($i++);
}
}
函数myFunc($i=0){
if($i<10){//或任何其他防止“无限循环”的逻辑
//主代码
myFunc($i++);
}
}
我确信这是设计上不可能的
要求通过use语句传入所有“状态”。不能将标签作为引用传递
PHP分析错误:语法错误,意外的“\u条目\u点\u 2\u 0”
(T_字符串),应为“&”或变量(T_变量)
函数在自己的作用域中运行,没有对标签的引用,这意味着需要以某种方式将其传回
有以下几点
This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one.
将变量传递给goto也是无效的
PHP Parse error: syntax error, unexpected '$goto' (T_VARIABLE), expecting identifier (T_STRING)
尽管所有这些都可能是一件好事,正如goto所说的,逻辑流程是错误的,但您将能够找到一种更为正确且不需要去做的方法来构建它
编辑:
更新2后为什么不做
if(your lambda() == something) {
Continue;
}
对不起,我在手机上写了密码。这似乎做了同样的事情,而且可读性更高,因此您不能跳过匿名/lambda函数中的循环迭代。但是您可以返回一个值,比较main函数中的值,然后从那里跳过迭代。听起来很简单,对吧 编辑:如果您还想从lamba中分离,可以使用相同的策略
function water() {
$lambda = function() { /*...*/; };
while (true) {
// Call the lambda function and store the return value.
$return = $lambda();
// If the return value was 'skip this iteration', well... skip it.
// Note: I'd normally compare to false, null or similar.
if ($return == 'skip this iteration') {
continue;
}
elseif ($return == "we're done!") {
break;
}
// Do stuff here.
}
}
我需要在一个表达式中实现它——执行lambda和goto必须打包在单个表达式中
因此,从你上次的评论中,我现在部分理解了你为什么有这个要求。但还不完全清楚。您已经编写了一个脚本,将此代码注入到一些预先存在的函数中,但不知道周围的环境。但是,goto标签是否已经到位?在任何情况下,您的问题可能都很简单:您希望代码仅为一行。但这是可能的,PHP中的代码只能跨一行。这不是最漂亮的,但它很好用
function water() {
while (true) {
if (function() { /*...*/; }() == 'skip this iteration') { continue; /* Or goto */ }
// Do stuff here.
}
}
也许您正试图解决您尝试的解决方案,而不是您原来的问题。这个问题很难说
在我看来,像是do while
loop:
do {
// ... some code
} while ((function() { /*...*/ ; return $k !== 0;})());
现在不允许应用这样的匿名函数。此外,需要显式声明闭包参数。因此,我的解决方案需要这样写:
function water()
{
_Entry_point_2_0:
// ... some code
goto (function() { /*...*/ ;return '_Entry_point_2_0';})();
// ... some code
}
$k = 10;
$f = function() use (&$k) { /*...*/ ; return $k !== 0; };
do {
// some code
} while ( $f() );
如果要使用“逗号运算符”,只需创建一个函数,该函数接受任意数量的参数并返回最后一个:
function begin(){
return func_get_args()[func_num_args()-1];
}
begin(expression1, expression2, expression3); // ==> result of expression3
一个函数的所有参数都会被求值,因此在参数互不依赖的情况下,它也会这样做 你能详细说明一下这段代码最后应该完成什么吗?现在我很难完全理解你的问题,它看起来有点像XY问题。@greenoldman你的函数能返回真还是假?然后可以在while循环中使用它:
while(function())代码>我不确定我是否理解。你想做一个无限循环,在这个循环中lambda不断地重新调用自己吗?我认为必须有一种方法来编写相同的逻辑,而不需要标签,并试图向后弯曲。。。PHP缺少一个逗号运算符,迫使您陷入不可能的境地。。。?嗯…内部函数在做什么。似乎可以用循环来代替?是的,通常我可以,但这不是我的需要——我必须“翻译”递归调用到函数内部体的手动循环。这就是重点。电话没问题:-)谢谢你的帮助。我知道后藤的局限性,这就是为什么我要问如何以某种方式做魔术。至于continue
——我需要添加break
s,这并不简单,但更糟糕的是,我仍然存在标签和单个表达式的问题<代码>如果
是语句。@greenoldman标签不是字符串!label是用户定义的关键字,php中没有动态标签定义。请检查此项以了解限制。非常感谢你。它非常接近,但PHP没有放弃:-)我需要使它成为单个表达式。我在想这样的代码my_lambda()?转到标签:转到标签
。对于我来说,逻辑是可以的,但是goto
不是表达式,三元运算符需要表达式。我不能使用if
,因为它们是语句。我是说你不应该首先使用goto。我还是不明白