Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# F#返回函数_C#_Function_F#_Return_Contains - Fatal编程技术网

C# F#返回函数

C# F#返回函数,c#,function,f#,return,contains,C#,Function,F#,Return,Contains,我是F#的新手,有点玩儿,我已经和C#合作过了。最近让我有点困惑的一件事是在函数中返回值。我不认为一切都是一个表达式(如上所述),并且以下代码不会编译或执行: let foo x = if x = 0 then x + 2 //The compiler will complain here due to a missing else branch. x - 2 相反,你必须写下: let foo x = if x = 0 then x + 2 else x - 2 我

我是F#的新手,有点玩儿,我已经和C#合作过了。最近让我有点困惑的一件事是在函数中返回值。我不认为一切都是一个表达式(如上所述),并且以下代码不会编译或执行:

let foo x =
   if x = 0 then x + 2 //The compiler will complain here due to a missing else branch.
   x - 2
相反,你必须写下:

let foo x =
   if x = 0 then x + 2
   else x - 2
我明白这是为什么了,当有一个循环时也会出现类似的问题

但是考虑一个函数,它等于C中的一个列表的“包含”函数:

相反,您可能会编写这样的递归函数:

let rec Contains (num : int) list =
   match list with
   |  [] -> false
   |  head::tail -> head = num || (Contains num tail)

我很同意,但在某些情况下,很难进行模式匹配。真的没有办法做上述的事情吗?难道一个人不能使用像收益率这样的关键词(或者类似于C#中的“return”)吗?

在C#中,早期的
return
实际上只是一个GOTO。我会认为这是坏的风格,除了“保镖模式”(验证)。那里的争论通常是尽早摆脱精神负担。鉴于F#的表达能力,大多数验证都可以通过类型进行,因此不需要(或至少不需要)其他无处不在的
if param=null | | invalid(param)return
样式。一旦你接受了功能性风格,你会发现对它的需求越来越少。如果需要,您始终可以模拟goto:-)


C#中的早期
返回
,实际上只是一个GOTO。我会认为这是坏的风格,除了“保镖模式”(验证)。那里的争论通常是尽早摆脱精神负担。鉴于F#的表达能力,大多数验证都可以通过类型进行,因此不需要(或至少不需要)其他无处不在的
if param=null | | invalid(param)return
样式。一旦你接受了功能性风格,你会发现对它的需求越来越少。如果需要,您始终可以模拟goto:-)


我同意你的观点:C语言中的早期退出非常方便,特别是通过避免嵌套的
if
来提高可读性

在F#中,为了避免嵌套的
if
或太大的模式匹配(即,案例太多或输入元组包含太多项),我们可以提取子函数:使用有意义的名称,它可以提高代码的可读性


对于C#中的列表和序列(
IEnumerable
),使用内置方法或LINQ的代码通常比使用/foreach循环的
更具声明性。这并不总是正确的,但值得一试 我同意你的观点:C语言中的早期退出非常方便,特别是通过避免嵌套的
if
来提高可读性

在F#中,为了避免嵌套的
if
或太大的模式匹配(即,案例太多或输入元组包含太多项),我们可以提取子函数:使用有意义的名称,它可以提高代码的可读性

对于C#中的列表和序列(
IEnumerable
),使用内置方法或LINQ的代码通常比使用/foreach
循环的
更具声明性。这并不总是正确的,但值得一试 请记住,F#编译器将尾部递归转换为循环。因此,解决方案实际上是使用尾部递归辅助函数,即使您使用的类型没有F#list的模式匹配支持。一些例子:

包含任何
IEnumerable
的方法:

用于
系统.Collections.Generic.List
的类似方法:

C#版本:

T ShortCircuit<T>(Func<T, bool> shouldReturn, Func<T, T> getNextValue, T seed) {
    while (true)
    {
        if (shouldReturn(seed))
            return seed;
        seed = getNextValue(seed);
    }
}
T短路(Func shouldReturn、Func getNextValue、T seed){
while(true)
{
如果(应该返回(种子))
返回种子;
seed=getNextValue(seed);
}
}
当然,这些例子只是作为教学练习的说明。正如Romain Deneau所指出的,在生产代码中,您需要使用库函数,如
Seq.contains
List.contains
,等等。

请记住,F编译器将尾部递归转换为循环。因此,解决方案实际上是使用尾部递归辅助函数,即使您使用的类型没有F#list的模式匹配支持。一些例子:

包含任何
IEnumerable
的方法:

用于
系统.Collections.Generic.List
的类似方法:

C#版本:

T ShortCircuit<T>(Func<T, bool> shouldReturn, Func<T, T> getNextValue, T seed) {
    while (true)
    {
        if (shouldReturn(seed))
            return seed;
        seed = getNextValue(seed);
    }
}
T短路(Func shouldReturn、Func getNextValue、T seed){
while(true)
{
如果(应该返回(种子))
返回种子;
seed=getNextValue(seed);
}
}

当然,这些例子只是作为教学练习的说明。正如Romain Deneau所指出的,在生产代码中,您需要使用库函数,如
Seq.contains
List.contains
,等等。

我不知道F,但我知道您不应该逐字逐句地在不同语言之间进行翻译。拥抱功能性风格!试着在这里使用高阶函数。我知道你不应该逐字翻译,这确实是个坏主意,但在某些情况下,在C#中使用类似的样式会很有用。你能举个例子吗?C#在循环中中断或返回的解决方案非常简单。学习List、Seq和Array模块中的函数。首先,看看tryFind。模块功能确实非常通用。那些特殊的,例如List.max,可以使用更通用的实现。不管你的C#循环做什么,都可以用这些函数来实现。意大利面代码de luxe可能是个例外,但在翻译成F#之前先把它清理干净。我不知道F#,但我知道你不应该逐字逐句地在不同语言之间翻译。拥抱功能性风格!尝试在这里使用更高阶的函数。我知道你不应该逐字翻译,这确实是个坏主意,但在某些情况下,使用类似C#的样式会很有用。你能举一个/一些例子吗?C#中断或返回的解决方案
exception Ret of string

let needsEarlyReturn foos =
    try
        for f in foos do
            if f > 42 then Ret "don't do" |> raise
            // more code
            if f > 7 then Ret "that ever" |> raise
        "!"
    with Ret v -> v
let contains item (xs : int seq) =
    use e = xs.GetEnumerator()
    let rec helper() = e.MoveNext() && (e.Current = item || helper())
    helper()
let contains item (xs : ResizeArray<int>) =
    let rec helper i = i < xs.Count && (xs.[i] = item || helper (i + 1)) 
    helper 0
let shortCircuitLoop shouldReturn getNextValue seed =
    let rec helper accumulator =
        if shouldReturn accumulator then accumulator else helper (getNextValue accumulator)
    helper seed
T ShortCircuit<T>(Func<T, bool> shouldReturn, Func<T, T> getNextValue, T seed) {
    while (true)
    {
        if (shouldReturn(seed))
            return seed;
        seed = getNextValue(seed);
    }
}