F#:函数中有更多返回点,如何处理它们? [英] F#: More return points in functions, how to handle them?

查看:55
本文介绍了F#:函数中有更多返回点,如何处理它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在复杂函数中返回值时遇到问题.例子总是更好:

考虑以下功能:

 让myf(mypar:int)=mypar + 1 

这里没有内容,该函数已正确编译,签名为:

  val myf:int->整型 

好的,很好.现在考虑以下代码:

 让myf(mypar:int)=如果mypar = 2,则4(*错误*)mypar + 1 

这不起作用:

该表达式应具有类型单位,但此处具有int

当我在 if while for for 或其他任何容器中时,每次尝试从函数返回时都会引发此错误堵塞.我以为问题是要确保所有可能的返回路径都返回相同的类型,但是在这里我不明白会发生什么.

请注意,如果我插入一个()单元,那么一切正常,例如:

 让myf(mypar:int)=如果mypar = 2,则()(*没有错误*)mypar + 1 

但是该单元不能使我的函数返回!!!它继续!!!此外,能否请您解释一下F#如何处理此问题??

谢谢

解决方案

要添加更多详细信息,您的方法的问题在于F#中的所有内容都是表达式.这使得对程序进行推理变得容易得多(因为您不需要跟踪当前正在执行的语句),但这意味着您始终必须编写一个完整的表达式.

如果您尝试编写类似 return 之类的东西,就好像您在C#中编写了以下内容一样(这可能解释了为什么F#不允许这种事情):

  int a = 10 +(3 *(返回10; 2));返回 

为什么在编写 if .. then()时没有收到错误消息?()表达式会创建一个特殊的 unit 类型的值,因为它只有一个有效值.F#允许您在返回 unit 时编写 if .. then 而无需 else ,因为它可以弄清楚 else 分支必须返回唯一的现有单位值,因此它将代码视为:

 如果有则()else()//由编译器隐式添加 

唯一的区别是抛出一个异常(使用 raise ),该异常的行为与C#中的行为相同.您可以使用异常来破坏函数,但是最好重写代码以具有完整的有效表达式.

I have a problem when returning values in complex functions. Examples are always better:

Consider the following function:

let myf (mypar: int) =
   mypar + 1

Well no probel here, this function is compiled correctly and the signature is:

val myf: int -> int

OK, well. Now consider this code:

let myf (mypar: int) =
   if mypar = 2 then
      4 (* ERROR *)
   mypar + 1

This does not work:

This expression was expected to have type unit but here has int

This error is raised everytime I try to return from my function when I am inside a if, a while a for or every other block. I thought that the problem was assuring that all possible return paths return the same type, but here I do not understand what happens.

Please note that if I insert a () unit everything works for example:

let myf (mypar: int) =
   if mypar = 2 then
      () (* No error *)
   mypar + 1

But that unit does not make my function return!!! it continues!!! Furthermore, could you please explain me how F# handles this???

Thankyou

解决方案

To add some more details, the problem with your approach is that everything in F# is an expression. This makes it a lot easier to reason about your programs (because you don't need to keep track of the currently executing statement), but it means that you always have to write a complete expression.

If you try to write something like return, it would be as if you wrote the following in C# (This probably explains why F# doesn't allow this kind of things):

int a = 10 + (3 * (return 10; 2));
return a;

Why didn't you get error when you wrote if .. then ()? The () expression creates a value of type unit that is special, because it has only one valid value. F# allows you to write if .. then without else when returning unit, because it can figure out that the else branch has to return the only existing unit value, so it sees your code as:

if something then ()
else () // implicitly added by the compiler

The only difference is throwing an exception (using raise) which behaves just like in C#. You could break out of a function using exception, but it is much better idea to rewrite the code to have a complete valid expression.

这篇关于F#:函数中有更多返回点,如何处理它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆