3

我在 C 语言中有这种 Duff 的设备,它工作正常(将文本格式化为钱):

#include <stdio.h>
#include <string.h>

char *money(const char *src, char *dst)
{
    const char *p = src;
    char *q = dst;
    size_t len;

    len = strlen(src);
    switch (len % 3) {
        do {
            *q++ = ',';
            case 0: *q++ = *p++;
            case 2: *q++ = *p++;
            case 1: *q++ = *p++;
        } while (*p);
    }
    *q++ = 0;
    return dst;
}

int main(void)
{
    char str[] = "1234567890123";
    char res[32];

    printf("%s\n", money(str, res));
    return 0;
}

输出:

1,234,567,890,123

但是我在尝试在 Javascript 中实现相同的功能时遇到了问题:

function money(src, dst) {
    var len = src.length;
    var i = 0;

    switch (len % 3) {
        do {
            dst += ',';
            case 0: dst += src[i++];
            case 2: dst += src[i++];
            case 1: dst += src[i++];
        } while (src[i]);
    }
    return dst;
}

var str = "1234567890123";
var res = "";

console.log(money(str, res));

nodejs 返回此错误:

        do {
        ^^
SyntaxError: Unexpected token do

我的问题是:javascript 是否支持计算的 GOTO 语句?

PD:我不想要替代方案,我只想知道为什么不起作用。

相关问题:Duff 的设备是否支持其他语言?

4

2 回答 2

5

我的问题是:javascript 是否支持计算的 GOTO 语句?

不是真的

PD:我不想要替代方案,我只想知道为什么不起作用。

它不起作用,因为在 JavaScript 中,switch语句只能包含caseblocks

尽管可能不是在寻找解决方法,但其他人可能会在寻找这个问题时找到一个,所以无论如何我都会提供一个。
这要归功于 mnieper,他在asm.js提出了建议。

基本思想是while(true)在顶层有一个循环,在switch里面有一个语句。

goto:
while(true)
{
    switch(where)
    {
        // no breaks
        case 0:
            // some code...
        case 1:
            // some other code...
        // ...
    }
}

为了模拟 goto,可以使用

where = 1;
continue goto;

但是,为了模拟 duff 的设备,只需将循环设为外部结构,并在 switch 语句中使用一个变量,该变量在第一次迭代后设置为一个值,该值将触发 switch 语句从它的第一个开始案子。

所以在你的情况下,这意味着交换switchdo...while()添加一个default案例和一个控制变量:

var where = len % 3;
do {
    switch (where) {
        default: dst += ',';
        case 0:  dst += src[i++];
        case 2:  dst += src[i++];
        case 1:  dst += src[i++];
    }
    where = -1;
} while (src[i]);

一般来说,这种方法的一个巨大缺点当然是它不能跨回调工作,回调在 JavaScript 中几乎无处不在。
但是,只要在单个顺序上下文中使用它,它就应该起作用。

有关更多信息,请参阅asm.js 存储库上发布的票证

于 2016-05-03T23:17:25.470 回答
2

JavaScriptswitch语句不是这样工作的。

switch (expr) {
  case expr:
    statements;
    break;
  case expr:
    statements;
    break;
  default:
    statements;
    break;
}

但是 JavaScript 确实提供了标签来控制你的循环

来自 MDN 的示例

var itemsPassed = 0;
var i, j;

top:
for (i = 0; i < items.length; i++){
  for (j = 0; j < tests.length; j++) {
    if (!tests[j].pass(items[i])) {
      continue top;
    }
  }

  itemsPassed++;
}

另一个来自 MDN 的例子

var allPass = true;
var i, j;

top:
for (i = 0; items.length; i++)
  for (j = 0; j < tests.length; i++)
    if (!tests[j].pass(items[i])){
      allPass = false;
      break top;
    }
于 2016-05-03T22:50:30.260 回答