使用for循环语法创建一个函数

时间:2013-05-01 14:59:19

标签: javascript coding-style

是否可以使用“for循环”样式语法创建函数?如果是这样,那个函数风格会被称为什么?

例如,for循环遵循以下语法:

for(i = 0; i < 10; i++)
{
    //do something
}

是否可以用任何语言创建自己的函数,例如,可以像这样调用的“myFunction”:

myFunction(x; y; z)
{
   //do something
}

(注意函数输入的分号而不是逗号,然后是块包装器)

通常在编程语言中,您只能创建一个函数并像这样调用它:

myFunction(input1, input2, input2);

所以基本上我希望能够创建一个接受输入的函数,以分号和代码块分隔,就像for循环一样。这可能吗?这叫什么?

编辑 - 澄清:我不打算编写一个运行循环的快捷方式功能。我正在寻找一个编写功能,从语法的角度来看,它看起来像一个for循环。但是,组合功能永远不会称之为“for”或出于任何原因。

编辑 - 这可以在“编译器”级别实现吗?我理解JavaScript中最接近的东西是以下(但它不像for一样干净):

myFunction(x, y, z, function()
{
    //do something
});

5 个答案:

答案 0 :(得分:3)

嗯......正如您已经说过:您可以创建自己的方法,但不能创建关键字。 for是一个关键字,关键字不必遵守哪种方法的规范。

我能想到的最接近的是:

void MyForLoop<T>(Func<T> myInitialization, Func<T, bool> myCondition, Func<T, T> myIteration, Action<T> myBody)
{
   // Check the arguments for null's.
    T iterator = myInitialization();
    while(myCondition(iterator))
    {
         myBody(value);
         value = myIteration(value);
    }
}

你可以这样称呼:

MyForLoop(() => 0, i => i < 10, i => i + 1, i => Console.WriteLine(i));

答案 1 :(得分:1)

您正在寻找创建新的DSL(域特定语言)。 Java,python,javascript和其他语言确实支持不同的范围。 DSL有时可能涉及特殊的语法,就像你想用分号做的那样,或者它可以像编写一个非常好的API(想想jQuery)一样简单。 JavaScript不支持自定义语法,但语言非常具有表现力,并且很容易创建一个类似于英语的api。

话虽这么说,你可以继续以你想要的方式编写你的代码然后通过某种解析器运行它并转换它。你应该看一下coffeescript的来源。您基本上需要熟悉编写自己的语言,创建语法,将事物解析为语法树和翻译代码。

就像我说的,其他语言确实支持创建自己的语法/ DSL。以下是一些资源:
- http://www.slideshare.net/Siddhi/creating-domain-specific-languages-in-python
- http://www.jetbrains.com/mps/

就我个人而言,我认为只要你有自定义语法,对于从事这个项目工作的新人来说就会非常困惑。但是,也许它对你正在做的事情有意义。

答案 2 :(得分:0)

您的确切语法在JavaScript中是不可能的,但您想要的目的是什么。您想要的内容与现代浏览器中forEach上提供的Array非常相似。

function myLooper(iterations, callback) {
    for(var i = 0; i < iterations; ++i) {
        callback(i);
    }
}

myLooper(4, function(i) {
    console.log(i);
});

// outputs
// 0
// 1
// 2
// 3

以上是fiddle

由于您还使用C#对其进行了标记,因此这是一个C#版本:

void MyLooper(int iterations, Action<int> action) {
    for(int i = 0; i < iterations; ++i) {
        action.Invoke(i);
    }
 }

我现在没有方便的C#环境,所以上面的内容可能不太正确。

答案 3 :(得分:0)

你在c#中要求一个解决方案,如果f#中的某些东西(这些语言可以“一起使用”)也很受欢迎,那么我可以提供以下代码片段(注意分离不是分号,因为你希望,但有空格):

函数yourLoop接受三个参数两个整数:lowerBound upperBound和一个函数(副作用更具体地说是类型'a - &gt;单位):body 具有

的含义
yourLoop (lowerBound:int) upperBound body

具有相同的效果
for i in lowerBound..upperBound do
  body(i)

该功能如下:

let rec yourLoop (lowerBound:int) upperBound body =
  if (lowerBound >= upperBound) then body upperBound
  else
    body lowerBound
    yourLoop (lowerBound+1) upperBound body 

例如,让它成为某种方法的主体

let something i = printfn "%s%i" "do something with " i

然后申请

yourLoop 0 5 something

产量

do something with 0
do something with 1
do something with 2
do something with 3
do something with 4
do something with 5

同样,如果你想要自上而下循环,那么你可以写

let rec yourInvertedLoop lowerBound upperBound body =
  if (lowerBound >= upperBound) then body lowerBound
  else
    body upperBound
    yourInvertedLoop (lowerBound) (upperBound-1) body

屈服

yourInvertedLoop 0 5 something

do something with 5
do something with 4
do something with 3
do something with 2
do something with 1
do something with 0

对于更通用的功能,请考虑

let rec yourLoopIncr lowerBound upperBound next body =
  if (next lowerBound >= upperBound) then body lowerBound
  else
    body lowerBound
    yourLoopIncr (next lowerBound) upperBound next body 

您可以在其中指定循环的迭代方式。例如,

yourLoopIncr 1 25 (fun x-> 2*x) something

将产生

do something with 1
do something with 2
do something with 4
do something with 8
do something with 16

备注:请注意,此解决方案仅适用于不返回值的实体。当然你仍然可以在控制台上写东西或改变变量等。例如代码

let mutable x = 0
let somethingElse n = x <- x+n 
yourLoop 0 10 somethingElse

将x设置为值55。

答案 4 :(得分:0)

您希望函数接受以分号分隔的输入,为什么不将输入连接到由分号分隔的一个字符串中!如果这对您有意义,那么只需在数组中输入所有输入并在数组上执行.join(';')。或者只是传递数组本身,如果分号不是您的特定要求。